1196 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			1196 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/* d4write.c   (c)Copyright Sequiter Software Inc., 1988-1996.  All rights reserved. */
 | 
						|
 | 
						|
#include "d4all.h"
 | 
						|
#ifndef S4UNIX
 | 
						|
   #ifdef __TURBOC__
 | 
						|
      #pragma hdrstop
 | 
						|
   #endif  /* __TURBOC__ */
 | 
						|
#endif  /* S4UNIX */
 | 
						|
 | 
						|
#ifndef S4OFF_WRITE
 | 
						|
#ifdef S4CLIENT
 | 
						|
 | 
						|
int S4FUNCTION d4writeLow( DATA4 *d4, const long recIn, const int unlock )
 | 
						|
{
 | 
						|
   int rc ;
 | 
						|
   CODE4 *c4 ;
 | 
						|
   CONNECTION4 *connection ;
 | 
						|
   CONNECTION4WRITE_INFO_IN info ;
 | 
						|
   CONNECTION4WRITE_INFO_OUT *out ;
 | 
						|
   long rec ;
 | 
						|
   #ifndef S4OFF_MEMO
 | 
						|
      CONNECTION4MEMO memo ;
 | 
						|
      F4MEMO *mfield ;
 | 
						|
      int i ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef S4VBASIC
 | 
						|
      if ( c4parm_check( d4, 2, E92601 ) )
 | 
						|
         return 0 ;
 | 
						|
   #endif  /* S4VBASIC */
 | 
						|
 | 
						|
   if ( recIn == -1 )
 | 
						|
      rec = d4recNo( d4 ) ;
 | 
						|
   else
 | 
						|
      rec = recIn ;
 | 
						|
 | 
						|
   #ifdef E4PARM_HIGH
 | 
						|
      if ( d4 == 0 )
 | 
						|
         return error4( 0, e4parm_null, E92601 ) ;
 | 
						|
      if ( rec == 0 || rec < -1 || d4->codeBase == 0 )
 | 
						|
         return error4( d4->codeBase, e4parm, E92601 ) ;
 | 
						|
      #ifdef E4ANALYZE
 | 
						|
         if ( d4->dataFile == 0 )
 | 
						|
            return error4( d4->codeBase, e4parm, E92601 ) ;
 | 
						|
         if ( d4->dataFile->connection == 0 )
 | 
						|
            return error4( d4->codeBase, e4parm, E92601 ) ;
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
 | 
						|
   c4 = d4->codeBase ;
 | 
						|
   if ( error4code( c4 ) < 0 )
 | 
						|
      return e4codeBase ;
 | 
						|
 | 
						|
   if ( d4->readOnly == 1 )
 | 
						|
      return error4describe( c4, e4write, E80606, d4alias( d4 ), 0, 0 ) ;
 | 
						|
 | 
						|
   /* ensure the record is being written to a valid position */
 | 
						|
   if ( rec > d4recCount( d4 ) + d4lockTestAppend( d4 ) )
 | 
						|
      return error4describe( c4, e4write, E82601, d4alias( d4 ), 0, 0 ) ;
 | 
						|
 | 
						|
   memset( &info, 0, sizeof( CONNECTION4WRITE_INFO_IN ) ) ;
 | 
						|
   connection = d4->dataFile->connection ;
 | 
						|
   connection4assign( connection, CON4WRITE, data4clientId( d4 ), data4serverId( d4 ) ) ;
 | 
						|
   #ifndef S4OFF_MEMO
 | 
						|
      for ( i = 0 ; i < d4->dataFile->nFieldsMemo ; i++ )
 | 
						|
      {
 | 
						|
         mfield = d4->fieldsMemo + i ;
 | 
						|
         if ( mfield->isChanged == 1 )
 | 
						|
            info.numMemoFields++ ;
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
   info.recNo = rec ;
 | 
						|
   info.unlock = unlock ;
 | 
						|
   connection4addData( connection, &info, sizeof( CONNECTION4WRITE_INFO_IN ), 0 ) ;
 | 
						|
   connection4addData( connection, d4->record, dfile4recWidth( d4->dataFile ), 0 ) ;
 | 
						|
   #ifndef S4OFF_MEMO
 | 
						|
      for ( i = 0 ; i < d4->dataFile->nFieldsMemo ; i++ )
 | 
						|
      {
 | 
						|
         mfield = d4->fieldsMemo + i ;
 | 
						|
         if ( mfield->isChanged == 1 )
 | 
						|
         {
 | 
						|
            memo.fieldNum = i ;
 | 
						|
            memo.memoLen = mfield->len ;
 | 
						|
            connection4addData( connection, &memo, sizeof( CONNECTION4MEMO ), 1 ) ;
 | 
						|
            if ( mfield->len > 0 )
 | 
						|
               connection4addData( connection, mfield->contents, mfield->len, 1 ) ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
   rc = connection4repeat( connection, -2, -1, -1, d4 ) ;
 | 
						|
   if ( rc == r4locked )
 | 
						|
      return rc ;
 | 
						|
   if ( rc < 0 )
 | 
						|
      return connection4error( connection, c4, rc, E92601 ) ;
 | 
						|
   if ( connection4len( connection ) != sizeof( CONNECTION4WRITE_INFO_OUT ) )
 | 
						|
      return error4( c4, e4packetLen, E92601 ) ;
 | 
						|
   out = (CONNECTION4WRITE_INFO_OUT *)connection4data( connection ) ;
 | 
						|
   if ( out->recordLocked == 1 )
 | 
						|
      d4localLockSet( d4, d4recNo( d4 ) ) ;
 | 
						|
 | 
						|
   if ( rc > 0 )  /* eg. r4entry or r4locked */
 | 
						|
      return rc ;
 | 
						|
   d4->recordChanged = 0 ;
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
 | 
						|
#else
 | 
						|
static int d4unwriteKeys( DATA4 *, const long ) ;
 | 
						|
 | 
						|
int S4FUNCTION d4writeLow( DATA4 *d4, const long recIn, const int unlock )
 | 
						|
{
 | 
						|
   long rec ;
 | 
						|
   int rc, finalRc, old ;
 | 
						|
   CODE4 *c4 ;
 | 
						|
   #ifndef S4OFF_TRAN
 | 
						|
      int hasTran ;
 | 
						|
      unsigned long len ;
 | 
						|
      TRAN4 *trans = 0 ;
 | 
						|
      long connectionId = 0L ;
 | 
						|
      long recNo ;
 | 
						|
      #ifndef S4OFF_MEMO
 | 
						|
         unsigned int ptrLen ;
 | 
						|
         char *ptr, *tempRecord ;
 | 
						|
         #ifdef S4MFOX
 | 
						|
            long type ;
 | 
						|
         #endif
 | 
						|
         long entry ;
 | 
						|
         unsigned long tempLong ;
 | 
						|
         unsigned long zero = 0L ;
 | 
						|
      #endif
 | 
						|
   #endif
 | 
						|
   #ifndef S4OFF_MEMO
 | 
						|
      int i ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef S4VBASIC
 | 
						|
      if ( c4parm_check( d4, 2, E92601 ) )
 | 
						|
         return 0 ;
 | 
						|
   #endif  /* S4VBASIC */
 | 
						|
 | 
						|
   #ifdef E4PARM_HIGH
 | 
						|
      if ( d4 == 0 )
 | 
						|
         return error4( 0, e4parm_null, E92601 ) ;
 | 
						|
      if ( recIn < -1 || recIn == 0 || d4->codeBase == 0 )
 | 
						|
         return error4( d4->codeBase, e4parm, E92601 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( recIn == -1 )
 | 
						|
      rec = d4recNo( d4 ) ;
 | 
						|
   else
 | 
						|
      rec = recIn ;
 | 
						|
 | 
						|
   c4 = d4->codeBase ;
 | 
						|
   if ( error4code( c4 ) < 0 )
 | 
						|
      return e4codeBase ;
 | 
						|
 | 
						|
   if ( d4->readOnly == 1 )
 | 
						|
      return error4describe( c4, e4write, E80606, d4alias( d4 ), 0, 0 ) ;
 | 
						|
 | 
						|
   old = d4->recordChanged ;
 | 
						|
   d4->recordChanged = 0 ;
 | 
						|
 | 
						|
   /* set lock before transaction handling since cannot otherwise rollback */
 | 
						|
   #ifndef S4OFF_MULTI
 | 
						|
      #ifdef S4SERVER
 | 
						|
         rc = dfile4lock( d4->dataFile, data4clientId( d4 ), data4serverId( d4 ), rec ) ;
 | 
						|
      #else
 | 
						|
         rc = d4lock( d4, rec ) ;
 | 
						|
      #endif
 | 
						|
      if ( rc )
 | 
						|
      {
 | 
						|
         d4->recordChanged = old ;
 | 
						|
         return rc ;
 | 
						|
      }
 | 
						|
   #endif  /* S4OFF_MULTI */
 | 
						|
 | 
						|
   /* ensure the record is being written to a valid position */
 | 
						|
   #ifdef S4OFF_MULTI
 | 
						|
      if ( rec > d4recCount( d4 ) + 1 )
 | 
						|
   #else
 | 
						|
      if ( rec > d4recCount( d4 ) + dfile4lockTestAppend( d4->dataFile, data4clientId( d4 ), data4serverId( d4 ) ) )
 | 
						|
   #endif
 | 
						|
   {
 | 
						|
      d4->recordChanged = old ;
 | 
						|
      return error4( c4, e4write, E82601 ) ;
 | 
						|
   }
 | 
						|
 | 
						|
   #ifndef S4OFF_TRAN
 | 
						|
      hasTran = 0 ;
 | 
						|
      if ( d4->logVal != LOG4TRANS )
 | 
						|
         if ( code4transEnabled( c4 ) )
 | 
						|
            if ( ( code4tranStatus( c4 ) == r4inactive ) )  /* start a mini-transaction */
 | 
						|
            {
 | 
						|
               rc = code4tranStartSingle( c4 ) ;
 | 
						|
               if ( rc != 0 )
 | 
						|
               {
 | 
						|
                  d4->recordChanged = old ;
 | 
						|
                  return rc ;
 | 
						|
               }
 | 
						|
               hasTran = 1 ;
 | 
						|
            }
 | 
						|
   #endif
 | 
						|
   /* 0. Validate memo id's */
 | 
						|
   /* 1. Update Keys */
 | 
						|
   /* 2. Update Memo Information */
 | 
						|
   /* 3. Update Data FILE4 */
 | 
						|
 | 
						|
   #ifndef S4OFF_MEMO
 | 
						|
      #ifndef S4OFF_MULTI
 | 
						|
         if ( d4->dataFile->nFieldsMemo > 0 )
 | 
						|
            if ( ( rc = d4validateMemoIds( d4 ) ) != 0 )
 | 
						|
            {
 | 
						|
               d4->recordChanged = old ;
 | 
						|
               #ifndef S4OFF_TRAN
 | 
						|
                  if ( hasTran )
 | 
						|
                     code4tranRollbackSingle( c4 ) ;
 | 
						|
               #endif
 | 
						|
               return rc ;
 | 
						|
            }
 | 
						|
      #endif  /* S4OFF_MULTI */
 | 
						|
   #endif  /* S4OFF_MEMO */
 | 
						|
 | 
						|
   #ifndef S4OFF_TRAN
 | 
						|
      if ( code4transEnabled( c4 ) )
 | 
						|
         if ( code4tranStatus( c4 ) == r4active )
 | 
						|
         {
 | 
						|
            trans = code4trans( c4 ) ;
 | 
						|
            #ifndef S4STAND_ALONE
 | 
						|
               connectionId = connection4id( c4->currentClient->connection ) ;
 | 
						|
            #endif
 | 
						|
            recNo = d4recNo( d4 ) ;
 | 
						|
            rc = tran4set( trans, trans->currentTranStatus, -1L, connectionId, TRAN4WRITE,
 | 
						|
                 sizeof( recNo ) + 2 * dfile4recWidth( d4->dataFile ), data4clientId( d4 ), data4serverId( d4 ) ) ;
 | 
						|
            if ( rc < 0 )
 | 
						|
            {
 | 
						|
               if ( hasTran )
 | 
						|
                  code4tranRollbackSingle( c4 ) ;
 | 
						|
               d4->recordChanged = old ;
 | 
						|
               return 0 ;
 | 
						|
            }
 | 
						|
            if ( tran4putData( trans, &recNo, sizeof( recNo ) ) == e4memory )
 | 
						|
            {
 | 
						|
               if ( hasTran )
 | 
						|
                  code4tranRollbackSingle( c4 ) ;
 | 
						|
               d4->recordChanged = old ;
 | 
						|
               return 0 ;
 | 
						|
            }
 | 
						|
            if ( d4readOld( d4, rec ) < 0 )
 | 
						|
            {
 | 
						|
               d4->recordChanged = old ;
 | 
						|
               return -1 ;
 | 
						|
            }
 | 
						|
            if ( tran4putData( trans, d4->recordOld, dfile4recWidth( d4->dataFile ) ) == e4memory )
 | 
						|
            {
 | 
						|
               if ( hasTran )
 | 
						|
                  code4tranRollbackSingle( c4 ) ;
 | 
						|
               d4->recordChanged = old ;
 | 
						|
               return 0 ;
 | 
						|
            }
 | 
						|
            if ( tran4putData( trans, d4record( d4 ), dfile4recWidth( d4->dataFile ) ) == e4memory )
 | 
						|
            {
 | 
						|
               if ( hasTran )
 | 
						|
                  code4tranRollbackSingle( c4 ) ;
 | 
						|
               d4->recordChanged = old ;
 | 
						|
               return 0 ;
 | 
						|
            }
 | 
						|
            len = trans->header.dataLen ;
 | 
						|
            #ifndef S4OFF_MEMO
 | 
						|
               /* First cycle through the fields to be flushed */
 | 
						|
               ptr = 0 ;
 | 
						|
               ptrLen = 0 ;
 | 
						|
 | 
						|
               for ( i = 0; i < d4->dataFile->nFieldsMemo; i++ )
 | 
						|
               {
 | 
						|
                  if ( d4->fieldsMemo[i].isChanged == 1 )
 | 
						|
                  {
 | 
						|
                     tempRecord = d4->record ;
 | 
						|
                     d4->record = d4->recordOld ;
 | 
						|
                     entry = f4long( d4->fieldsMemo[i].field ) ;
 | 
						|
                     d4->record = tempRecord ;
 | 
						|
 | 
						|
                     if ( entry == 0 )
 | 
						|
                     {
 | 
						|
                        if ( tran4putData( trans, &zero, sizeof( zero ) ) == e4memory )
 | 
						|
                        {
 | 
						|
                           rc = e4memory ;
 | 
						|
                           break ;
 | 
						|
                        }
 | 
						|
                        len += sizeof( zero ) ;
 | 
						|
                     }
 | 
						|
                     else
 | 
						|
                     {
 | 
						|
                        #ifdef S4MFOX
 | 
						|
                           rc = memo4fileRead( &d4->dataFile->memoFile, entry, &ptr, &ptrLen, &type ) ;
 | 
						|
                        #else
 | 
						|
                           rc = memo4fileRead( &d4->dataFile->memoFile, entry, &ptr, &ptrLen ) ;
 | 
						|
                        #endif
 | 
						|
                        if ( rc < 0 )
 | 
						|
                           break ;
 | 
						|
                        tempLong = ptrLen;
 | 
						|
                        if ( tran4putData( trans, &tempLong, sizeof( tempLong ) ) == e4memory )
 | 
						|
                        {
 | 
						|
                           rc = e4memory ;
 | 
						|
                           break ;
 | 
						|
                        }
 | 
						|
                        len += sizeof( tempLong ) ;
 | 
						|
                        if ( ptrLen > 0 )
 | 
						|
                        {
 | 
						|
                           if ( tran4putData( trans, ptr, ptrLen ) == e4memory )
 | 
						|
                           {
 | 
						|
                              rc = e4memory ;
 | 
						|
                              break ;
 | 
						|
                           }
 | 
						|
                           len += ptrLen ;
 | 
						|
                        }
 | 
						|
                     }
 | 
						|
                     tempLong = d4->fieldsMemo[i].len;
 | 
						|
                     if ( tran4putData( trans, &tempLong, sizeof( tempLong ) ) == e4memory )
 | 
						|
                     {
 | 
						|
                        rc = e4memory ;
 | 
						|
                        break ;
 | 
						|
                     }
 | 
						|
                     len += sizeof( tempLong ) ;
 | 
						|
                     if ( d4->fieldsMemo[i].len )
 | 
						|
                     {
 | 
						|
                        if ( tran4putData( trans, d4->fieldsMemo[i].contents, d4->fieldsMemo[i].len ) == e4memory )
 | 
						|
                        {
 | 
						|
                           rc = e4memory ;
 | 
						|
                           break ;
 | 
						|
                        }
 | 
						|
                        len += d4->fieldsMemo[i].len ;
 | 
						|
                     }
 | 
						|
                  }
 | 
						|
                  else
 | 
						|
                  {
 | 
						|
                     if ( tran4putData( trans, &zero, sizeof( zero ) ) == e4memory )
 | 
						|
                     {
 | 
						|
                        rc = e4memory ;
 | 
						|
                        break ;
 | 
						|
                     }
 | 
						|
                     if ( tran4putData( trans, &zero, sizeof( zero ) ) == e4memory )
 | 
						|
                     {
 | 
						|
                        rc = e4memory ;
 | 
						|
                        break ;
 | 
						|
                     }
 | 
						|
                     len += 2 * sizeof( zero ) ;
 | 
						|
                  }
 | 
						|
               }
 | 
						|
 | 
						|
               u4free( ptr ) ;
 | 
						|
               ptr = 0 ;
 | 
						|
               ptrLen = 0 ;
 | 
						|
               if ( rc < 0 )
 | 
						|
               {
 | 
						|
                  if ( hasTran )
 | 
						|
                     code4tranRollbackSingle( c4 ) ;
 | 
						|
                  d4->recordChanged = old ;
 | 
						|
                  return error4stack( c4, (short)rc, E92601 ) ;
 | 
						|
               }
 | 
						|
               trans->header.dataLen = (unsigned short int)len ;
 | 
						|
            #endif  /* S4OFF_MEMO */
 | 
						|
 | 
						|
            rc = tran4lowAppend( trans, 0 ) ;
 | 
						|
            if ( rc != 0 )
 | 
						|
            {
 | 
						|
               if ( hasTran )
 | 
						|
                  code4tranRollbackSingle( c4 ) ;
 | 
						|
               d4->recordChanged = old ;
 | 
						|
               return rc ;
 | 
						|
            }
 | 
						|
         }
 | 
						|
   #endif /* S4OFF_TRAN */
 | 
						|
 | 
						|
   #ifndef S4INDEX_OFF
 | 
						|
      rc = d4writeKeys( d4, rec ) ;
 | 
						|
   #endif
 | 
						|
   d4->recordChanged = old ;
 | 
						|
   #ifndef S4INDEX_OFF
 | 
						|
      if ( rc )
 | 
						|
      {
 | 
						|
         #ifndef S4OFF_TRAN
 | 
						|
            if ( hasTran )
 | 
						|
               code4tranRollbackSingle( c4 ) ;
 | 
						|
         #endif
 | 
						|
         return rc ;
 | 
						|
      }
 | 
						|
   #endif
 | 
						|
 | 
						|
   finalRc = 0 ;
 | 
						|
 | 
						|
   #ifndef S4OFF_MEMO
 | 
						|
      /* First cycle through the fields to be flushed */
 | 
						|
      for ( i = 0; i < d4->dataFile->nFieldsMemo; i++ )
 | 
						|
      {
 | 
						|
         rc = f4memoUpdate( d4->fieldsMemo[i].field) ;
 | 
						|
         if ( rc < 0 )
 | 
						|
         {
 | 
						|
            #ifndef S4OFF_TRAN
 | 
						|
               if ( hasTran )
 | 
						|
                  code4tranRollbackSingle( c4 ) ;
 | 
						|
            #endif
 | 
						|
            return error4stack( c4, (short)rc, E92601 ) ;
 | 
						|
         }
 | 
						|
         if ( rc > 0 )
 | 
						|
            finalRc = rc ;
 | 
						|
      }
 | 
						|
   #endif  /* S4OFF_MEMO */
 | 
						|
 | 
						|
   rc = d4writeData( d4, rec ) ;
 | 
						|
   if ( rc < 0 )
 | 
						|
      d4unwriteKeys( d4, rec ) ;
 | 
						|
   #ifndef S4OFF_TRAN
 | 
						|
      if ( rc < 0 )
 | 
						|
         if ( code4transEnabled( c4 ) )
 | 
						|
            if ( code4tranStatus( c4 ) == r4active )
 | 
						|
            {
 | 
						|
               rc = tran4set( trans, trans->currentTranStatus, -1L,
 | 
						|
                    connectionId, TRAN4VOID, (unsigned int)0, data4clientId( d4 ), data4serverId( d4 ) ) ;
 | 
						|
               if ( rc < 0 )
 | 
						|
               {
 | 
						|
                  if ( hasTran )
 | 
						|
                     code4tranRollbackSingle( c4 ) ;
 | 
						|
                  return rc ;
 | 
						|
               }
 | 
						|
               return tran4lowAppend( trans, "\0" ) ;
 | 
						|
            }
 | 
						|
   #else
 | 
						|
      if ( rc < 0 )
 | 
						|
         return rc ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifndef S4OFF_TRAN
 | 
						|
      if ( hasTran )
 | 
						|
         code4tranCommitSingle( c4 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( unlock )   /* unlock records (unless entire file is locked)... */
 | 
						|
   {
 | 
						|
      #ifdef S4SERVER
 | 
						|
         if ( dfile4lockTestFile( d4->dataFile, data4clientId( d4 ), data4serverId( d4 ) ) == 0 )
 | 
						|
            return dfile4unlockData( d4->dataFile, data4clientId( d4 ), data4serverId( d4 ) ) ;
 | 
						|
      #else
 | 
						|
         #ifndef S4OFF_TRAN
 | 
						|
            if ( code4transEnabled( c4 ) )
 | 
						|
               if ( code4tranStatus( c4 ) == r4active )
 | 
						|
                  return 0 ;
 | 
						|
         #endif
 | 
						|
         #ifndef S4OFF_MULTI
 | 
						|
            if ( d4lockTestFile( d4 ) == 0 )
 | 
						|
            {
 | 
						|
               rc = d4unlock( d4 ) ;
 | 
						|
               if ( rc == r4active )  /* just a transactional notification */
 | 
						|
                  return 0 ;
 | 
						|
               return rc ;
 | 
						|
            }
 | 
						|
         #endif
 | 
						|
      #endif
 | 
						|
   }
 | 
						|
 | 
						|
   return finalRc ;
 | 
						|
}
 | 
						|
 | 
						|
int d4writeData( DATA4 *data, const long rec )
 | 
						|
{
 | 
						|
   #ifndef S4OFF_MULTI
 | 
						|
      int rc ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   #ifdef E4PARM_HIGH
 | 
						|
      if ( data == 0 )
 | 
						|
         return error4( 0, e4parm_null, E92602 ) ;
 | 
						|
      if ( rec < 1 || data->codeBase == 0 )
 | 
						|
         return error4( data->codeBase, e4parm, E92602 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( error4code( data->codeBase ) < 0 )
 | 
						|
      return e4codeBase ;
 | 
						|
 | 
						|
   #ifndef S4OFF_MULTI
 | 
						|
      #ifdef S4SERVER
 | 
						|
         rc = dfile4lock( data->dataFile, data4clientId( data ), data4serverId( data ), rec ) ;
 | 
						|
      #else
 | 
						|
         rc = d4lock( data, rec ) ;
 | 
						|
      #endif
 | 
						|
      if ( rc )
 | 
						|
         return rc ;
 | 
						|
   #endif  /* S4OFF_MULTI */
 | 
						|
 | 
						|
   data->recordChanged = 0 ;
 | 
						|
   return dfile4writeData( data->dataFile, rec, data->record ) ;
 | 
						|
}
 | 
						|
 | 
						|
int dfile4writeData( DATA4FILE *d4, const long rec, const char *record )
 | 
						|
{
 | 
						|
   #ifdef E4PARM_LOW
 | 
						|
      if ( d4 == 0 )
 | 
						|
         return error4( 0, e4parm_null, E91102 ) ;
 | 
						|
      if ( rec < 1 || d4->c4 == 0 )
 | 
						|
         return error4( d4->c4, e4parm, E91102 ) ;
 | 
						|
   #endif
 | 
						|
 | 
						|
   if ( error4code( d4->c4 ) < 0 )
 | 
						|
      return e4codeBase ;
 | 
						|
 | 
						|
   d4->fileChanged = 1 ;
 | 
						|
   return file4write( &d4->file, dfile4recordPosition(d4, rec), record, d4->recWidth ) ;
 | 
						|
}
 | 
						|
 | 
						|
#ifndef S4OFF_TRAN
 | 
						|
/* search the removed list for the specified keys/char combination.
 | 
						|
   if recno is 0, then the matching character entry is returned */
 | 
						|
TAG4KEY_REMOVED *t4keyFind( TAG4 *tag, long recno, char *key )
 | 
						|
{
 | 
						|
   TAG4KEY_REMOVED *found ;
 | 
						|
 | 
						|
   for ( found = 0 ; ; )
 | 
						|
   {
 | 
						|
      found =(TAG4KEY_REMOVED *)l4next( &tag->removedKeys, found ) ;
 | 
						|
      if ( found == 0 )
 | 
						|
         break ;
 | 
						|
      if ( recno == 0 )
 | 
						|
      {
 | 
						|
         if ( c4memcmp( key, found->key, (unsigned int)tag->tagFile->header.keyLen ) == 0 )
 | 
						|
            return found ;
 | 
						|
      }
 | 
						|
      else
 | 
						|
         if ( found->recno == recno )
 | 
						|
            if ( c4memcmp( key, found->key, (unsigned int)tag->tagFile->header.keyLen ) == 0 )
 | 
						|
               return found ;
 | 
						|
   }
 | 
						|
 | 
						|
   return 0 ;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
int d4writeKeys( DATA4 *d4, const long rec )
 | 
						|
{
 | 
						|
   #ifdef S4INDEX_OFF
 | 
						|
      return 0 ;
 | 
						|
   #else
 | 
						|
      unsigned char newKeyBuf[I4MAX_KEY_SIZE] ;
 | 
						|
      unsigned char *tempPtr ;
 | 
						|
      char *saveRecBuffer ;
 | 
						|
      unsigned char *oldKey ;
 | 
						|
      int rc, rc2, saveError, keyLen, oldKeyAdded, addNewKey ;
 | 
						|
      TAG4 *tagOn ;
 | 
						|
      TAG4FILE *tagFileOn ;
 | 
						|
      CODE4 *c4 ;
 | 
						|
      #ifndef S4OFF_MULTI
 | 
						|
         int indexLocked ;
 | 
						|
      #endif
 | 
						|
      #ifndef S4OFF_TRAN
 | 
						|
         TAG4KEY_REMOVED *removed ;
 | 
						|
      #endif
 | 
						|
      #ifdef S4FOX
 | 
						|
         int newKeyLen ;
 | 
						|
      #endif
 | 
						|
 | 
						|
      #ifdef E4PARM_HIGH
 | 
						|
         if ( d4 == 0 )
 | 
						|
            return error4( 0, e4parm_null, E92604 ) ;
 | 
						|
         if ( rec < 1 || d4->codeBase == 0 )
 | 
						|
            return error4( d4->codeBase, e4parm, E92604 ) ;
 | 
						|
      #endif
 | 
						|
 | 
						|
      c4 = d4->codeBase ;
 | 
						|
      d4->bofFlag = d4->eofFlag = 0 ;
 | 
						|
 | 
						|
      #ifdef S4CB51
 | 
						|
         #ifndef S4OFF_MULTI
 | 
						|
            #ifdef S4SERVER
 | 
						|
               rc = dfile4lock( d4->dataFile, data4clientId( d4 ), data4serverId( d4 ), rec, d4 ) ;
 | 
						|
            #else
 | 
						|
               rc = d4lock( d4, rec ) ;
 | 
						|
            #endif
 | 
						|
            if ( rc )
 | 
						|
               return rc ;
 | 
						|
         #endif  /* S4OFF_MULTI */
 | 
						|
      #endif
 | 
						|
 | 
						|
      #ifdef N4OTHER
 | 
						|
         if ( d4->dataFile->tagfiles.nLink > 0 )
 | 
						|
      #else
 | 
						|
         if ( d4->dataFile->indexes.nLink > 0 )
 | 
						|
      #endif
 | 
						|
      {
 | 
						|
         if ( d4readOld( d4, rec ) < 0 )
 | 
						|
            return -1 ;
 | 
						|
         if ( u4memcmp( d4->recordOld, d4->record, dfile4recWidth( d4->dataFile )) == 0 )
 | 
						|
            return 0 ;
 | 
						|
      }
 | 
						|
 | 
						|
      saveRecBuffer = d4->record ;
 | 
						|
      rc = 0 ;
 | 
						|
      #ifndef S4OFF_MULTI
 | 
						|
         #ifdef S4SERVER
 | 
						|
            indexLocked = dfile4lockTestIndex( d4->dataFile, data4serverId( d4 ) ) ? 2 : 0 ;  /* 2 means was user locked */
 | 
						|
         #else
 | 
						|
            indexLocked = d4lockTestIndex( d4 ) ? 2 : 0 ;  /* 2 means was user locked */
 | 
						|
         #endif
 | 
						|
      #endif
 | 
						|
 | 
						|
      for( tagOn = 0 ;; )
 | 
						|
      {
 | 
						|
         tagOn = d4tagNext( d4, tagOn ) ;
 | 
						|
         if ( tagOn == 0 )
 | 
						|
            break ;
 | 
						|
 | 
						|
         tagFileOn = tagOn->tagFile ;
 | 
						|
         oldKeyAdded = addNewKey = 1 ;
 | 
						|
         tagOn->added = tagOn->removed = 0 ;
 | 
						|
 | 
						|
         rc2 = expr4context( tagFileOn->expr, d4 ) ;
 | 
						|
         if ( rc2 < 0 )
 | 
						|
         {
 | 
						|
            rc = rc2 ;
 | 
						|
            break ;
 | 
						|
         }
 | 
						|
         if ( tagFileOn->filter != 0 )
 | 
						|
         {
 | 
						|
            rc2 = expr4context( tagFileOn->filter, d4 ) ;
 | 
						|
            if ( rc2 < 0 )
 | 
						|
            {
 | 
						|
               rc = rc2 ;
 | 
						|
               break ;
 | 
						|
            }
 | 
						|
         }
 | 
						|
         keyLen = tfile4exprKey( tagFileOn, &tempPtr ) ;
 | 
						|
         if ( keyLen < 0 )
 | 
						|
         {
 | 
						|
            rc = -1 ;
 | 
						|
            break ;
 | 
						|
         }
 | 
						|
         #ifdef E4ANALYZE
 | 
						|
            if ( keyLen != tagFileOn->header.keyLen || keyLen > I4MAX_KEY_SIZE)
 | 
						|
               return error4( c4, e4index, E92604 ) ;
 | 
						|
         #endif
 | 
						|
 | 
						|
         memcpy( (void *)newKeyBuf, tempPtr, (unsigned int)keyLen ) ;
 | 
						|
         #ifdef S4FOX
 | 
						|
            newKeyLen = keyLen ;
 | 
						|
         #endif
 | 
						|
 | 
						|
         if ( tagFileOn->filter )
 | 
						|
            addNewKey = expr4true( tagFileOn->filter ) ;
 | 
						|
 | 
						|
         d4->record = d4->recordOld ;
 | 
						|
 | 
						|
         rc2 = expr4context( tagFileOn->expr, d4 ) ;
 | 
						|
         if ( rc2 < 0 )
 | 
						|
         {
 | 
						|
            rc = rc2 ;
 | 
						|
            break ;
 | 
						|
         }
 | 
						|
         if ( tagFileOn->filter != 0 )
 | 
						|
         {
 | 
						|
            rc2 = expr4context( tagFileOn->filter, d4 ) ;
 | 
						|
            if ( rc2 < 0 )
 | 
						|
            {
 | 
						|
               rc = rc2 ;
 | 
						|
               break ;
 | 
						|
            }
 | 
						|
         }
 | 
						|
         if ( tagFileOn->filter )
 | 
						|
            oldKeyAdded = expr4true( tagFileOn->filter ) ;
 | 
						|
         keyLen = tfile4exprKey( tagOn->tagFile, &oldKey ) ;
 | 
						|
 | 
						|
         d4->record = saveRecBuffer ;
 | 
						|
 | 
						|
         if ( keyLen < 0 )
 | 
						|
         {
 | 
						|
            rc = keyLen ;
 | 
						|
            break ;
 | 
						|
         }
 | 
						|
         if ( oldKeyAdded == addNewKey )
 | 
						|
            #ifdef S4FOX
 | 
						|
               if ( u4keycmp( (void *)newKeyBuf, oldKey, (unsigned int)keyLen, (unsigned int)newKeyLen, 0, &tagFileOn->vfpInfo ) == 0 )
 | 
						|
            #else
 | 
						|
               if ( u4memcmp( (void *)newKeyBuf, oldKey, (unsigned int)keyLen ) == 0 )
 | 
						|
            #endif
 | 
						|
                continue ;
 | 
						|
 | 
						|
         #ifndef S4OFF_MULTI
 | 
						|
            if ( indexLocked == 0 )
 | 
						|
            {
 | 
						|
               indexLocked = 1 ;
 | 
						|
               #ifdef S4SERVER
 | 
						|
                  rc = dfile4lockIndex( d4->dataFile, data4serverId( d4 ) ) ;
 | 
						|
               #else
 | 
						|
                  rc = d4lockIndex( d4 ) ;
 | 
						|
               #endif
 | 
						|
               if ( rc )
 | 
						|
                  break ;
 | 
						|
            }
 | 
						|
         #endif  /* S4OFF_MULTI */
 | 
						|
 | 
						|
         if ( oldKeyAdded )
 | 
						|
         {
 | 
						|
            tagOn->removed = 1 ;
 | 
						|
            #ifndef S4OFF_TRAN
 | 
						|
               if ( code4tranStatus( c4 ) == r4active && ( t4unique( tagOn ) == r4unique ||
 | 
						|
                    t4unique( tagOn ) == e4unique
 | 
						|
                    #ifdef S4FOX
 | 
						|
                       || t4unique( tagOn ) == r4candidate
 | 
						|
                    #endif
 | 
						|
                    ) )  /* save the entry due to transactions */
 | 
						|
               {
 | 
						|
                  removed = (TAG4KEY_REMOVED *)u4allocFree( c4, (long)sizeof( LINK4 ) + (long)sizeof( long ) + tagFileOn->header.keyLen ) ;
 | 
						|
                  if ( removed == 0 )
 | 
						|
                  {
 | 
						|
                     rc = e4memory ;
 | 
						|
                     break ;
 | 
						|
                  }
 | 
						|
                  removed->recno = rec ;
 | 
						|
                  memcpy( removed->key, oldKey, (unsigned int)tagFileOn->header.keyLen ) ;
 | 
						|
                  l4addBefore( &tagOn->removedKeys, l4first( &tagOn->removedKeys ), removed ) ;
 | 
						|
               }
 | 
						|
               else
 | 
						|
               {
 | 
						|
            #endif
 | 
						|
               rc2 = expr4context( tagFileOn->expr, d4 ) ;
 | 
						|
               if ( rc2 < 0 )
 | 
						|
               {
 | 
						|
                  rc = rc2 ;
 | 
						|
                  break ;
 | 
						|
               }
 | 
						|
               if ( tagFileOn->filter != 0 )
 | 
						|
               {
 | 
						|
                  rc2 = expr4context( tagFileOn->filter, d4 ) ;
 | 
						|
                  if ( rc2 < 0 )
 | 
						|
                  {
 | 
						|
                     rc = rc2 ;
 | 
						|
                     break ;
 | 
						|
                  }
 | 
						|
               }
 | 
						|
 | 
						|
               if ( tfile4remove( tagFileOn, oldKey, rec ) < 0 )
 | 
						|
               {
 | 
						|
                  rc = -1 ;
 | 
						|
                  break ;
 | 
						|
               }
 | 
						|
            #ifndef S4OFF_TRAN
 | 
						|
               }
 | 
						|
            #endif
 | 
						|
         }
 | 
						|
 | 
						|
         #ifndef S4OFF_TRAN
 | 
						|
            if ( code4tranStatus( c4 ) == r4rollback && ( t4unique( tagOn ) == r4unique ||
 | 
						|
                 t4unique( tagOn ) == e4unique
 | 
						|
                 #ifdef S4FOX
 | 
						|
                    || t4unique( tagOn ) == r4candidate
 | 
						|
                 #endif
 | 
						|
                 ) )  /* remove the removal due to transactions */
 | 
						|
            {
 | 
						|
               removed = t4keyFind( tagOn, rec,(char *)newKeyBuf ) ;
 | 
						|
               if ( removed != 0 )  /* means the record really was not deleted, so just remove from the list of to-be-removed */
 | 
						|
               {
 | 
						|
                  l4remove( &tagOn->removedKeys, removed ) ;
 | 
						|
                  u4free( removed ) ;
 | 
						|
                  addNewKey = 0 ;
 | 
						|
               }
 | 
						|
               /* else: removed is null when, within the same transaction,
 | 
						|
                  a record alteration is made to replace the key that was to
 | 
						|
                  be removed.  At that point, the key was actually removed,
 | 
						|
                  so it must now be added back */
 | 
						|
            }
 | 
						|
         #endif
 | 
						|
         if ( addNewKey )
 | 
						|
         {
 | 
						|
            tagOn->added = 1 ;
 | 
						|
            rc2 = expr4context( tagFileOn->expr, d4 ) ;
 | 
						|
            if ( rc2 < 0 )
 | 
						|
            {
 | 
						|
               rc = rc2 ;
 | 
						|
               break ;
 | 
						|
            }
 | 
						|
            if ( tagFileOn->filter != 0 )
 | 
						|
            {
 | 
						|
               rc2 = expr4context( tagFileOn->filter, d4 ) ;
 | 
						|
               if ( rc2 < 0 )
 | 
						|
               {
 | 
						|
                  rc = rc2 ;
 | 
						|
                  break ;
 | 
						|
               }
 | 
						|
            }
 | 
						|
            #ifndef S4OFF_TRAN
 | 
						|
               /* if a unique tag, first check if the record may have instead been pre-deleted */
 | 
						|
               if ( t4unique( tagOn ) != 0 )
 | 
						|
               {
 | 
						|
                  removed = t4keyFind( tagOn, 0L, (char *)newKeyBuf ) ;
 | 
						|
                  if ( removed != 0 )   /* re-adding a key that was removed, so really remove this entry from the tag file first */
 | 
						|
                  {
 | 
						|
                     if ( tfile4remove( tagFileOn, removed->key, removed->recno ) < 0 )
 | 
						|
                     {
 | 
						|
                        rc = -1 ;
 | 
						|
                        break ;
 | 
						|
                     }
 | 
						|
                     l4remove( &tagOn->removedKeys, removed ) ;
 | 
						|
                     u4free( removed ) ;
 | 
						|
                  }
 | 
						|
               }
 | 
						|
            #endif
 | 
						|
            rc = tfile4add( tagFileOn, newKeyBuf, rec, t4unique( tagOn ) ) ;
 | 
						|
            if ( rc == r4unique || rc == e4unique )
 | 
						|
            {
 | 
						|
               saveError = error4set( c4, 0 ) ;
 | 
						|
 | 
						|
               #ifndef S4OFF_TRAN
 | 
						|
                  if ( code4tranStatus( c4 ) == r4active && ( t4unique( tagOn ) == r4unique ||
 | 
						|
                       t4unique( tagOn ) == e4unique
 | 
						|
                       #ifdef S4FOX
 | 
						|
                          || t4unique( tagOn ) == r4candidate
 | 
						|
                       #endif
 | 
						|
                       ) )  /* just remove from the removed list */
 | 
						|
                  {
 | 
						|
                     removed =(TAG4KEY_REMOVED *)l4first( &tagOn->removedKeys ) ;
 | 
						|
                     if ( removed == 0 )
 | 
						|
                     {
 | 
						|
                        error4( c4, e4info, E92604 ) ;
 | 
						|
                        error4set( c4, 0 ) ;
 | 
						|
                        rc = e4info ;
 | 
						|
                        break ;
 | 
						|
                     }
 | 
						|
                     l4remove( &tagOn->removedKeys, removed ) ;
 | 
						|
                     u4free( removed ) ;
 | 
						|
                  }
 | 
						|
                  else
 | 
						|
               #endif
 | 
						|
               if ( oldKeyAdded )
 | 
						|
               {
 | 
						|
                  rc2 = expr4context( tagFileOn->expr, d4 ) ;
 | 
						|
                  if ( rc2 < 0 )
 | 
						|
                  {
 | 
						|
                     rc = rc2 ;
 | 
						|
                     break ;
 | 
						|
                  }
 | 
						|
                  if ( tagFileOn->filter != 0 )
 | 
						|
                  {
 | 
						|
                     rc2 = expr4context( tagFileOn->filter, d4 ) ;
 | 
						|
                     if ( rc2 < 0 )
 | 
						|
                     {
 | 
						|
                        rc = rc2 ;
 | 
						|
                        break ;
 | 
						|
                     }
 | 
						|
                  }
 | 
						|
                  if ( tfile4add( tagFileOn, (unsigned char *)oldKey, rec, t4unique( tagOn ) ) < 0 )
 | 
						|
                  {
 | 
						|
                     rc = -1 ;
 | 
						|
                     break ;
 | 
						|
                  }
 | 
						|
               }
 | 
						|
 | 
						|
               /* Remove the keys which were just added */
 | 
						|
               for(;;)
 | 
						|
               {
 | 
						|
                  tagOn = d4tagPrev( d4, tagOn ) ;
 | 
						|
                  if ( tagOn == 0 )
 | 
						|
                     break ;
 | 
						|
                  tagFileOn = tagOn->tagFile ;
 | 
						|
 | 
						|
                  if ( tagOn->added )
 | 
						|
                  {
 | 
						|
                     d4->record = saveRecBuffer ;
 | 
						|
 | 
						|
                     rc2 = expr4context( tagFileOn->expr, d4 ) ;
 | 
						|
                     if ( rc2 < 0 )
 | 
						|
                     {
 | 
						|
                        rc = rc2 ;
 | 
						|
                        break ;
 | 
						|
                     }
 | 
						|
                     if ( tagFileOn->filter != 0 )
 | 
						|
                     {
 | 
						|
                        rc2 = expr4context( tagFileOn->filter, d4 ) ;
 | 
						|
                        if ( rc2 < 0 )
 | 
						|
                        {
 | 
						|
                           rc = rc2 ;
 | 
						|
                           break ;
 | 
						|
                        }
 | 
						|
                     }
 | 
						|
 | 
						|
                     rc2 = tfile4removeCalc( tagFileOn, rec ) ;
 | 
						|
                     if ( rc2 < 0 )
 | 
						|
                     {
 | 
						|
                        rc = rc2 ;
 | 
						|
                        break ;
 | 
						|
                     }
 | 
						|
                  }
 | 
						|
 | 
						|
                  if ( tagOn->removed )
 | 
						|
                  {
 | 
						|
                     d4->record = d4->recordOld ;
 | 
						|
 | 
						|
                     rc2 = expr4context( tagFileOn->expr, d4 ) ;
 | 
						|
                     if ( rc2 < 0 )
 | 
						|
                     {
 | 
						|
                        rc = rc2 ;
 | 
						|
                        break ;
 | 
						|
                     }
 | 
						|
                     if ( tagFileOn->filter != 0 )
 | 
						|
                     {
 | 
						|
                        rc2 = expr4context( tagFileOn->filter, d4 ) ;
 | 
						|
                        if ( rc2 < 0 )
 | 
						|
                        {
 | 
						|
                           rc = rc2 ;
 | 
						|
                           break ;
 | 
						|
                        }
 | 
						|
                     }
 | 
						|
                     rc2 = t4addCalc( tagOn, rec ) ;
 | 
						|
                     if ( rc2 < 0 )
 | 
						|
                     {
 | 
						|
                        d4->record = saveRecBuffer ;
 | 
						|
                        rc = rc2 ;
 | 
						|
                        break ;
 | 
						|
                     }
 | 
						|
                  }
 | 
						|
               }
 | 
						|
 | 
						|
               d4->record = saveRecBuffer ;
 | 
						|
 | 
						|
               error4set( c4, (short)saveError ) ;
 | 
						|
               if ( saveError < 0 )
 | 
						|
                  rc = saveError ;
 | 
						|
               break ;
 | 
						|
            }
 | 
						|
            if ( rc < 0 )   /* can't generate e4unique, so just set to -1 */
 | 
						|
            {
 | 
						|
               rc = -1 ;
 | 
						|
               break ;
 | 
						|
            }
 | 
						|
            rc = 0 ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
      #ifndef S4OFF_MULTI
 | 
						|
         if ( indexLocked == 1 )
 | 
						|
            dfile4unlockIndex( d4->dataFile, data4serverId( d4 ) ) ;
 | 
						|
      #endif
 | 
						|
 | 
						|
      d4->recNumOld = -1 ;
 | 
						|
      return rc ;
 | 
						|
   #endif  /* S4OFF_INDEX */
 | 
						|
}
 | 
						|
 | 
						|
static int d4unwriteKeys( DATA4 *d4, const long rec )
 | 
						|
{
 | 
						|
   #ifdef S4INDEX_OFF
 | 
						|
      return 0 ;
 | 
						|
   #else
 | 
						|
      unsigned char newKeyBuf[I4MAX_KEY_SIZE] ;
 | 
						|
      char *saveRecBuffer ;
 | 
						|
      unsigned char *oldKey, *tempPtr ;
 | 
						|
      int rc2, rc, keyLen, oldKeyAdded, addNewKey ;
 | 
						|
      #ifndef S4OFF_MULTI
 | 
						|
         int indexLocked ;
 | 
						|
      #endif
 | 
						|
      TAG4 *tagOn ;
 | 
						|
      TAG4FILE *tagFileOn ;
 | 
						|
      #ifndef S4OFF_TRAN
 | 
						|
         TAG4KEY_REMOVED *removed ;
 | 
						|
      #endif
 | 
						|
      #ifdef S4FOX
 | 
						|
         int newKeyLen ;
 | 
						|
      #endif
 | 
						|
 | 
						|
      #ifdef E4PARM_HIGH
 | 
						|
         if ( d4 == 0 )
 | 
						|
            return error4( 0, e4parm_null, E92605 ) ;
 | 
						|
         if ( rec < 1 || d4->codeBase == 0 )
 | 
						|
            return error4( d4->codeBase, e4parm, E92605 ) ;
 | 
						|
      #endif
 | 
						|
 | 
						|
      #ifdef N4OTHER
 | 
						|
         if ( d4->dataFile->tagfiles.nLink > 0 )
 | 
						|
      #else
 | 
						|
         if ( d4->dataFile->indexes.nLink > 0 )
 | 
						|
      #endif
 | 
						|
         if ( u4memcmp( d4->recordOld, d4->record, dfile4recWidth( d4->dataFile )) == 0 )
 | 
						|
            return 0 ;
 | 
						|
 | 
						|
      saveRecBuffer = d4->record ;
 | 
						|
 | 
						|
      rc = 0 ;
 | 
						|
      #ifndef S4OFF_MULTI
 | 
						|
         #ifdef S4SERVER
 | 
						|
            indexLocked = dfile4lockTestIndex( d4->dataFile, data4serverId( d4 ) ) ? 2 : 0 ;  /* 2 means was user locked */
 | 
						|
         #else
 | 
						|
            indexLocked = d4lockTestIndex( d4 ) ? 2 : 0 ;  /* 2 means was user locked */
 | 
						|
         #endif
 | 
						|
      #endif
 | 
						|
 | 
						|
      for( tagOn = 0 ;; )
 | 
						|
      {
 | 
						|
         tagOn = d4tagNext( d4, tagOn ) ;
 | 
						|
         if ( tagOn == 0 )
 | 
						|
            break ;
 | 
						|
 | 
						|
         tagFileOn = tagOn->tagFile ;
 | 
						|
         rc2 = expr4context( tagFileOn->expr, d4 ) ;
 | 
						|
         if ( rc2 < 0 )
 | 
						|
         {
 | 
						|
            rc = rc2 ;
 | 
						|
            break ;
 | 
						|
         }
 | 
						|
         if ( tagFileOn->filter != 0 )
 | 
						|
         {
 | 
						|
            rc2 = expr4context( tagFileOn->filter, d4 ) ;
 | 
						|
            if ( rc2 < 0 )
 | 
						|
            {
 | 
						|
               rc = rc2 ;
 | 
						|
               break ;
 | 
						|
            }
 | 
						|
         }
 | 
						|
 | 
						|
         oldKeyAdded = addNewKey = 1 ;
 | 
						|
 | 
						|
         keyLen = tfile4exprKey( tagFileOn, &tempPtr ) ;
 | 
						|
         if ( keyLen < 0 )
 | 
						|
         {
 | 
						|
            rc = keyLen ;
 | 
						|
            break ;
 | 
						|
         }
 | 
						|
         #ifdef E4ANALYZE
 | 
						|
            if ( keyLen != tagFileOn->header.keyLen || keyLen > I4MAX_KEY_SIZE)
 | 
						|
               return error4( d4->codeBase, e4index, E92605 ) ;
 | 
						|
         #endif
 | 
						|
 | 
						|
         memcpy( (void *)newKeyBuf, tempPtr, (unsigned int)keyLen ) ;
 | 
						|
         #ifdef S4FOX
 | 
						|
            newKeyLen = keyLen ;
 | 
						|
         #endif
 | 
						|
 | 
						|
         if ( tagFileOn->filter )
 | 
						|
            addNewKey = expr4true( tagFileOn->filter ) ;
 | 
						|
 | 
						|
         d4->record = d4->recordOld ;
 | 
						|
 | 
						|
         rc2 = expr4context( tagFileOn->expr, d4 ) ;
 | 
						|
         if ( rc2 < 0 )
 | 
						|
         {
 | 
						|
            rc = rc2 ;
 | 
						|
            break ;
 | 
						|
         }
 | 
						|
         if ( tagFileOn->filter != 0 )
 | 
						|
         {
 | 
						|
            rc2 = expr4context( tagFileOn->filter, d4 ) ;
 | 
						|
            if ( rc2 < 0 )
 | 
						|
            {
 | 
						|
               rc = rc2 ;
 | 
						|
               break ;
 | 
						|
            }
 | 
						|
         }
 | 
						|
 | 
						|
         if ( tagFileOn->filter )
 | 
						|
            oldKeyAdded = expr4true( tagFileOn->filter ) ;
 | 
						|
         keyLen = tfile4exprKey( tagFileOn, &oldKey ) ;
 | 
						|
 | 
						|
         d4->record = saveRecBuffer ;
 | 
						|
 | 
						|
         if ( keyLen < 0 )
 | 
						|
         {
 | 
						|
            rc = keyLen ;
 | 
						|
            break ;
 | 
						|
         }
 | 
						|
         if ( oldKeyAdded == addNewKey )
 | 
						|
            #ifdef S4FOX
 | 
						|
               if ( u4keycmp( (void *)newKeyBuf, oldKey, (unsigned int)keyLen, (unsigned int)newKeyLen, 0, &tagFileOn->vfpInfo ) == 0 )
 | 
						|
            #else
 | 
						|
               if ( u4memcmp( (void *)newKeyBuf, oldKey, (unsigned int)keyLen ) == 0 )
 | 
						|
            #endif
 | 
						|
                continue ;
 | 
						|
 | 
						|
         #ifndef S4OFF_MULTI
 | 
						|
            if ( indexLocked == 0 )
 | 
						|
            {
 | 
						|
               indexLocked = 1 ;
 | 
						|
               #ifdef S4SERVER
 | 
						|
                  rc = dfile4lockIndex( d4->dataFile, data4serverId( d4 ) ) ;
 | 
						|
               #else
 | 
						|
                  rc = d4lockIndex( d4 ) ;
 | 
						|
               #endif
 | 
						|
               if ( rc )
 | 
						|
                  break ;
 | 
						|
            }
 | 
						|
         #endif  /* S4OFF_MULTI */
 | 
						|
 | 
						|
         if ( oldKeyAdded )
 | 
						|
         {
 | 
						|
            #ifndef S4OFF_TRAN
 | 
						|
               if ( code4tranStatus( d4->codeBase ) == r4active && ( t4unique( tagOn ) == r4unique ||
 | 
						|
                    t4unique( tagOn ) == e4unique
 | 
						|
                    #ifdef S4FOX
 | 
						|
                       || t4unique( tagOn ) == r4candidate
 | 
						|
                    #endif
 | 
						|
                    ) )  /* save the entry due to transactions */
 | 
						|
               {
 | 
						|
                  for ( removed = 0 ;; )
 | 
						|
                  {
 | 
						|
                     removed = (TAG4KEY_REMOVED *)l4next( &tagOn->removedKeys, removed ) ;
 | 
						|
                     /* if a reindex occurs, then the list will be empty,
 | 
						|
                        so follow regular procedures.  Otherwise the key should
 | 
						|
                        be on the removed list */
 | 
						|
                     if ( removed == 0 )
 | 
						|
                        break ;
 | 
						|
                     if ( c4memcmp( removed->key, oldKey, (unsigned int)tagFileOn->header.keyLen ) == 0 && ( removed->recno == rec ) )
 | 
						|
                     {
 | 
						|
                        l4remove( &tagOn->removedKeys, removed ) ;
 | 
						|
                        u4free( removed ) ;
 | 
						|
                        break ;
 | 
						|
                     }
 | 
						|
                  }
 | 
						|
                  if ( rc < 0 )
 | 
						|
                     break ;
 | 
						|
               }
 | 
						|
               else
 | 
						|
               {
 | 
						|
            #endif
 | 
						|
               rc2 = expr4context( tagFileOn->expr, d4 ) ;
 | 
						|
               if ( rc2 < 0 )
 | 
						|
               {
 | 
						|
                  rc = rc2 ;
 | 
						|
                  break ;
 | 
						|
               }
 | 
						|
               if ( tagFileOn->filter != 0 )
 | 
						|
               {
 | 
						|
                  rc2 = expr4context( tagFileOn->filter, d4 ) ;
 | 
						|
                  if ( rc2 < 0 )
 | 
						|
                  {
 | 
						|
                     rc = rc2 ;
 | 
						|
                     break ;
 | 
						|
                  }
 | 
						|
               }
 | 
						|
               if ( tfile4add( tagFileOn, oldKey, rec, t4unique( tagOn ) ) < 0 )
 | 
						|
               {
 | 
						|
                  rc = -1 ;
 | 
						|
                  break ;
 | 
						|
               }
 | 
						|
            #ifndef S4OFF_TRAN
 | 
						|
               }
 | 
						|
            #endif
 | 
						|
         }
 | 
						|
 | 
						|
         #ifndef S4OFF_TRAN
 | 
						|
            if ( code4tranStatus( d4->codeBase ) == r4rollback && ( t4unique( tagOn ) == r4unique ||
 | 
						|
                 t4unique( tagOn ) == e4unique
 | 
						|
                 #ifdef S4FOX
 | 
						|
                    || t4unique( tagOn ) == r4candidate
 | 
						|
                 #endif
 | 
						|
                 ) )  /* remove the removal due to transactions */
 | 
						|
            {
 | 
						|
               rc = -1 ;
 | 
						|
               break ;
 | 
						|
            }
 | 
						|
            else
 | 
						|
         #endif
 | 
						|
         if ( addNewKey )
 | 
						|
         {
 | 
						|
            rc2 = expr4context( tagFileOn->expr, d4 ) ;
 | 
						|
            if ( rc2 < 0 )
 | 
						|
            {
 | 
						|
               rc = rc2 ;
 | 
						|
               break ;
 | 
						|
            }
 | 
						|
            if ( tagFileOn->filter != 0 )
 | 
						|
            {
 | 
						|
               rc2 = expr4context( tagFileOn->filter, d4 ) ;
 | 
						|
               if ( rc2 < 0 )
 | 
						|
               {
 | 
						|
                  rc = rc2 ;
 | 
						|
                  break ;
 | 
						|
               }
 | 
						|
            }
 | 
						|
            rc = tfile4remove( tagFileOn, newKeyBuf, rec ) ;
 | 
						|
            if ( rc == r4unique || rc == e4unique )
 | 
						|
            {
 | 
						|
               rc = -1 ;
 | 
						|
               break ;
 | 
						|
            }
 | 
						|
            if ( rc < 0 )
 | 
						|
            {
 | 
						|
               rc = -1 ;
 | 
						|
               break ;
 | 
						|
            }
 | 
						|
            rc = 0 ;
 | 
						|
         }
 | 
						|
      }
 | 
						|
      #ifndef S4OFF_MULTI
 | 
						|
         if ( indexLocked == 1 )
 | 
						|
            dfile4unlockIndex( d4->dataFile, data4serverId( d4 ) ) ;
 | 
						|
      #endif
 | 
						|
 | 
						|
      d4->recNumOld = -1 ;
 | 
						|
      return rc ;
 | 
						|
   #endif  /* S4OFF_INDEX */
 | 
						|
}
 | 
						|
#endif  /* S4CLIENT */
 | 
						|
#endif  /* S4OFF_WRITE */
 |