home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0010 - 0019 / ibm0010-0019 / ibm0010.tar / ibm0010 / CODE4-1.ZIP / SOURCE.ZIP / D4WRITE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-10-14  |  5.0 KB  |  202 lines

  1.  
  2. /*
  3.     d4write( base_ref, rec_num )   
  4.     (c)Copyright Sequiter Software Inc., 1987, 1988, 1989.  All rights reserved.
  5.  
  6.        Uses the 'old buffer'.
  7.        Writes the record from 'buffer' to the database.
  8.        All corresponding index files are kept up to date.
  9.        If 'rec_num' does not exist, the record will be appended.
  10. */
  11.  
  12. #include "d4base.h"
  13. #include "u4error.h"
  14.  
  15. #include <string.h>
  16. #include <time.h>
  17. #include <stdlib.h>
  18. #ifndef UNIX
  19.    #include <io.h>
  20. #endif
  21.  
  22. extern long   lseek(int, long, int) ;
  23. extern BASE  *v4base ;
  24. extern INDEX *v4index ;
  25.  
  26. extern int    v4cur_base ;
  27. extern int    v4unique_error ;
  28.  
  29.  
  30. int d4write( rec_num )
  31. long  rec_num ;
  32. {
  33.    int    index_on, do_append, rc ;
  34.    char  *key_ptr, buffer[34], *buf_ptr, key_data[MAX_KEY_SIZE+8] ;
  35.    BASE  *base_ptr  ;
  36.    INDEX *index_ptr ;
  37.  
  38.    long time_val ;   /* For Update Time */
  39.    struct tm  *tm_ptr ;
  40.  
  41.    if ( v4cur_base < 0 ) 
  42.    {
  43.       u4error( E_D_MISSING, (char *) 0 ) ; 
  44.       return( -1 ) ;
  45.    }
  46.  
  47.    base_ptr  =  v4base +  v4cur_base ;
  48.    buf_ptr   =  base_ptr->buffer ;
  49.  
  50.    if ( rec_num <= 0  ||  rec_num > d4reccount() )
  51.    {
  52.       /* Append Record */
  53.       d4lock( 0L,1 ) ;  /* Lock Record Count Bytes */
  54.       rec_num   =  d4reccount() + 1 ;
  55.       do_append =  1 ;
  56.    }
  57.    else
  58.    {
  59.       #ifndef SMALL
  60.      /* Make sure the Record has Changed to Avoid Extra Index File Work */
  61.      if ( base_ptr->index_ref >= 0 )
  62.      {
  63.         /* Read the Old Record into the Old Buffer */
  64.         base_ptr->buffer =  base_ptr->old_buf ;
  65.         rc =  d4go( rec_num) ;
  66.         base_ptr->buffer =  buf_ptr ;
  67.         if ( rc < 0 )  return -1 ;
  68.  
  69.         /* Return if the Record has not Changed */
  70.         if ( memcmp( base_ptr->old_buf, buf_ptr, base_ptr->buffer_len) == 0)
  71.            return 0 ;
  72.      }
  73.       #endif
  74.       do_append =  0 ;
  75.    }
  76.  
  77.    #ifndef SMALL
  78.    if ( v4unique_error)
  79.    {
  80.       /* Make sure no duplicate keys would be generated for unique key index files */
  81.       index_on =  base_ptr->index_ref ;
  82.       while ( index_on >= 0 )
  83.       {
  84.      index_ptr=  v4index +  index_on ;
  85.      if ( index_ptr->unique )
  86.      {
  87.         if( (key_ptr =  i4eval( index_on )) == (char *) 0)
  88.         {
  89.            d4unlock( 0L ) ;
  90.            return( -1) ;
  91.         }
  92.         if ( (rc =  i4seek( index_on, key_ptr )) < 0)
  93.         {
  94.            d4unlock( 0L ) ;
  95.            return( -1) ;
  96.         }
  97.         if ( rc == 0 && b4key(index_on)->rec_num != rec_num )
  98.         {
  99.            char buf[70] ;
  100.            d4unlock( 0L ) ;
  101.            c4key( key_ptr, buf, i4type(index_on) ) ;
  102.            u4error( E_UNIQUE, index_ptr->name, "Key:", buf, (char *) 0) ;
  103.            return( -2 ) ;
  104.         }
  105.      }
  106.      index_on =  v4index[ index_on ].prev ;
  107.       }
  108.    }
  109.    #endif
  110.  
  111.    if ( ! do_append )
  112.       if ( d4lock( rec_num, 1)  < 0)
  113.       {
  114.      d4unlock( 0L ) ;
  115.      return( -1) ;
  116.       }
  117.  
  118.    base_ptr->rec_num =  rec_num  ;
  119.  
  120.    /* Write the Record */
  121.    lseek( base_ptr->dos_file,
  122.       base_ptr->header_len+ (rec_num-1)* base_ptr->buffer_len, 0 ) ;
  123.    if ( write( base_ptr->dos_file, base_ptr->buffer, base_ptr->buffer_len)
  124.     !=  base_ptr->buffer_len )
  125.    {
  126.       d4unlock( 0L ) ;
  127.       ltoa( rec_num, buffer, 10) ;
  128.       u4error( E_WRITE, base_ptr->name, "Record Number:", buffer, (char *) 0 ) ;
  129.       return( -1) ;
  130.    }
  131.  
  132.    if ( do_append)
  133.    {
  134.       /* Record is being Appended */
  135.       if ( write( base_ptr->dos_file, "\x1A", 1) != 1)
  136.       {
  137.      d4unlock( 0L ) ;
  138.      ltoa( rec_num, buffer, 10) ;
  139.      u4error( E_WRITE, base_ptr->name, "Record Number:", buffer, (char *) 0 ) ;
  140.      return( -1) ;
  141.       }
  142.  
  143.       /* write the new size */
  144.       lseek( base_ptr->dos_file, (long)4, 0) ;
  145.       if ( write( base_ptr->dos_file, (char *) &rec_num, 4) != 4)
  146.       {
  147.      d4unlock( 0L ) ;
  148.      u4error( E_WRITE, base_ptr->name, "Record Count Bytes.", (char *) 0 ) ;
  149.      return( -1) ;
  150.       }
  151.       d4unlock( 0L ) ;
  152.    }
  153.  
  154.    #ifndef SMALL
  155.    /* Update the Index Files */
  156.    index_on =  base_ptr->index_ref ;
  157.    while ( index_on >= 0 )
  158.    {
  159.       key_ptr =  i4eval(index_on) ;
  160.       if ( key_ptr == (char *) 0)  return( -1 ) ;
  161.  
  162.       index_ptr =  v4index +  index_on ;
  163.  
  164.       if ( do_append )
  165.       {
  166.      if ( i4add( index_on, key_ptr, rec_num ) < 0)
  167.         return( -1 ) ;
  168.       }
  169.       else
  170.       {
  171.      memcpy( key_data, key_ptr, index_ptr->key_len ) ;
  172.  
  173.      base_ptr->buffer =  base_ptr->old_buf ;
  174.      key_ptr =  i4eval(index_on) ;
  175.      base_ptr->buffer =  buf_ptr ;
  176.      if ( key_ptr == (char *) 0)  return( -1 ) ;
  177.  
  178.      if ( memcmp( key_data, key_ptr, index_ptr->key_len ) != 0 )
  179.      {
  180.         /* Remove Old and Add New */
  181.         if ( i4remove( index_on, key_ptr, rec_num ) < 0)
  182.            return( -1 ) ;
  183.         if ( i4add( index_on, key_data, rec_num ) < 0)
  184.            return( -1 ) ;
  185.      }
  186.       }
  187.  
  188.       index_on =  index_ptr->prev ;
  189.    }
  190.    #endif
  191.  
  192.    /* Update the last Update Time */
  193.    time ( (time_t *) &time_val) ;
  194.    tm_ptr =  localtime( (time_t *) &time_val) ;
  195.  
  196.    base_ptr->yy =  (char) tm_ptr->tm_year  ;
  197.    base_ptr->mm =  (char) tm_ptr->tm_mon+1  ;
  198.    base_ptr->dd =  (char) tm_ptr->tm_mday  ;
  199.  
  200.    return( 0) ;
  201. }
  202.