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