home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c160 / 1.ddi / SOURCE / X4.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-19  |  11.8 KB  |  574 lines

  1. /*  x4.c    (c)Copyright Sequiter Software Inc., 1987-1990.  All rights reserved. */
  2.  
  3. #include  "d4all.h"
  4. #include  "u4error.h"
  5. #include  "p4misc.h"
  6.  
  7. #include  <stdlib.h>
  8. #include  <string.h>
  9.  
  10. extern BASE   *v4base ;
  11. extern INDEX  *v4index ;
  12. extern int     v4cur_base, v4lock_wait ;
  13.  
  14. extern X4FILTER  *v4filter ;
  15. extern X4RELATE  *v4relate ;
  16.  
  17.  
  18. #ifdef KR
  19.    int  x4filter( filter_routine )
  20.    int (*filter_routine)() ;
  21. #else
  22.    int  x4filter( int (*filter_routine)(void) )
  23. #endif
  24. {
  25.    BASE  *base_ptr ;
  26.  
  27.    base_ptr =  d4ptr() ;
  28.    if ( base_ptr == (BASE *) 0 )  return -1 ;  /* No Database is Selected */
  29.  
  30.    if ( v4filter == (X4FILTER *) 0 )
  31.       if ( h4create( (char **) &v4filter, 5, sizeof(X4FILTER), 3 ) < 0 )  return -1 ;
  32.  
  33.    base_ptr->filter_ref =  h4get( (char **) &v4filter, base_ptr->filter_ref ) ;
  34.    if ( base_ptr->filter_ref < 0 )   return -1 ; 
  35.  
  36.    v4filter[base_ptr->filter_ref].filter_routine =  filter_routine ;
  37.  
  38.    return 0 ;
  39. }
  40.  
  41.  
  42. x4blank()  /* Returns TRUE if the record is blank */
  43. {
  44.    char *ptr ;
  45.    int     i ;
  46.  
  47.    for ( i= 1; i<= f4num_fields(); i++ )
  48.    {
  49.       ptr =  f4str( f4j_ref(i) ) ;
  50.       while ( *ptr !=  (char) 0 )
  51.      if ( *ptr++ != ' ' )  return 0 ;
  52.    }
  53.  
  54.    return 1 ;
  55. }
  56.  
  57.  
  58.  
  59. int  x4filter_do()
  60. {
  61.    int    on, rc ;
  62.    BASE  *base_ptr ;
  63.  
  64.    if (v4filter == (X4FILTER *) 0)    return 0 ;
  65.  
  66.    base_ptr =  d4ptr() ;
  67.    if ( base_ptr == (BASE *) 0)  return -1 ;
  68.  
  69.    for ( on = base_ptr->filter_ref; on >= 0; on = v4filter[on].prev)
  70.    {
  71.       rc = (*v4filter[on].filter_routine)() ;
  72.       if ( rc < 0 )  return  -1 ;
  73.       if ( rc > 0 )  return   1 ;
  74.    }
  75.  
  76.    return 0 ;
  77. }
  78.  
  79.  
  80. x4relate( char *expr, int base_ref, int index_ref, long miss_code )
  81. {
  82.    BASE     *base_ptr ;
  83.    X4RELATE   *relate_ptr ;
  84.    char     *compile_ptr ;
  85.  
  86.    base_ptr =  d4ptr() ;
  87.    if ( base_ptr == (BASE *) 0 )
  88.    {
  89.       u4error( E_CONTROL, (char *) 0 ) ;
  90.       return -1 ;  /* No Database is Selected */
  91.    }
  92.  
  93.    if ( base_ref == v4cur_base )
  94.    {
  95.       u4error( E_RELATED, (char *) 0 ) ;
  96.       return -1 ;  /* No Database is Selected */
  97.    }
  98.  
  99.    if ( e4parse( expr, &compile_ptr ) < 0 )   return -1 ;
  100.    if ( e4exec( compile_ptr ) == (char *) 0 )
  101.    {
  102.       h4free_memory( compile_ptr ) ;
  103.       return -1 ;
  104.    }
  105.  
  106.    if ( v4relate == (X4RELATE *) 0 )
  107.       if ( h4create( (char **) &v4relate, 5, sizeof(X4RELATE), 3 )  < 0 )  return -1 ;
  108.  
  109.    base_ptr->relate_ref = h4get( (char **) &v4relate, base_ptr->relate_ref);
  110.    if ( base_ptr->relate_ref < 0 )  return -1 ;
  111.  
  112.    relate_ptr =  v4relate + base_ptr->relate_ref ;
  113.  
  114.    relate_ptr->control_base_ref =  d4select( -1 ) ;
  115.  
  116.    if ( index_ref >= 0 )
  117.       base_ref =  v4index[index_ref].base_ref ;
  118.  
  119.    relate_ptr->compile     =  compile_ptr ;
  120.    relate_ptr->base_ref  =  base_ref ;
  121.    relate_ptr->index_ref =  index_ref ;
  122.    relate_ptr->miss_code =  miss_code ;
  123.  
  124.    return 0 ;
  125. }
  126.  
  127. static  void  x4relate_error( X4RELATE *, char *) ;
  128.  
  129. static void  x4relate_error( X4RELATE *relate_ptr, char *msg )
  130. {
  131.    char  rec_str[34], *index_file ;
  132.  
  133.    d4select( relate_ptr->control_base_ref ) ;
  134.  
  135.    c4ltoa( d4recno(), rec_str, 8 ) ;
  136.    rec_str[8] = '\000' ;
  137.  
  138.    if ( relate_ptr->index_ref >= 0 )
  139.       index_file =  v4index[relate_ptr->index_ref].name ;
  140.    else
  141.       index_file =  "No Index File" ;
  142.  
  143.    u4error( E_RELATING, msg,
  144.              "Controlling Database:",
  145.              v4base[relate_ptr->control_base_ref].name,
  146.              "On Record Number: ", rec_str,
  147.              "Related Database:", v4base[relate_ptr->base_ref].name,
  148.              "Index File:", index_file,
  149.              (char *) 0 ) ;
  150. }
  151.  
  152. static  int  x4miss( X4RELATE * ) ;
  153.  
  154. static    x4miss( X4RELATE *relate_ptr )
  155. {
  156.    if ( relate_ptr->miss_code >= 1 )
  157.    {
  158.       if ( d4go( relate_ptr->miss_code ) < 0)
  159.       {
  160.      d4select( relate_ptr->control_base_ref ) ;
  161.      return -1 ;
  162.       }
  163.       return 0 ;
  164.    }
  165.  
  166.    memset( v4base[relate_ptr->base_ref].buffer, (int) ' ',
  167.        (size_t) v4base[relate_ptr->base_ref].buffer_len ) ;
  168.    v4base[relate_ptr->base_ref].rec_num =  -1L ;
  169.    if ( relate_ptr->miss_code != 0 )
  170.    {
  171.       x4relate_error( relate_ptr, "(No Record Located)" ) ;
  172.       return -1 ;
  173.    }
  174.  
  175.    return 0 ;
  176. }
  177.  
  178.  
  179. x4relate_do()
  180. {
  181.    int      on, old_base, rc, old_index ;
  182.    long   rec_num ;
  183.    char  *ptr ;
  184.    X4RELATE  *relate_ptr ;
  185.  
  186.    if ( (on = d4ptr()->relate_ref) < 0 )  return 0 ;
  187.  
  188.    old_base =  d4select( -1 ) ;
  189.    
  190.    for ( ; on >= 0; on =  relate_ptr->prev )
  191.    {
  192.       relate_ptr =  v4relate +  on ;
  193.  
  194.       if ( (ptr = (char *) e4exec(relate_ptr->compile)) == (char *) 0 )
  195.       {
  196.      d4select(old_base) ;
  197.      return -1 ;
  198.       }
  199.  
  200.       d4select( relate_ptr->base_ref ) ;
  201.       if ( relate_ptr->base_ref != v4cur_base )
  202.       {
  203.      x4relate_error( relate_ptr, "(Could not Select Related Database)");
  204.      d4select(old_base) ;
  205.      return -1 ;
  206.       }
  207.  
  208.       if ( relate_ptr->index_ref >= 0 )
  209.       {
  210.      old_index =  d4ptr()->current_index ;
  211.  
  212.      i4select( relate_ptr->index_ref ) ;
  213.      if ( i4seek_ref() != relate_ptr->index_ref)
  214.      {
  215.         x4relate_error( relate_ptr, "(Could not Select Related Index File)" ) ;
  216.         d4select(old_base) ;
  217.         return -1 ;
  218.      }
  219.  
  220.      rc =  d4seek( ptr ) ;
  221.      i4select( old_index ) ;
  222.  
  223.      if ( rc < 0 )
  224.      {
  225.         d4select(old_base) ;
  226.         return rc ;
  227.      }
  228.  
  229.      if ( rc > 1 )
  230.         if ( x4miss( relate_ptr ) < 0)
  231.         {
  232.            d4select(old_base) ;
  233.            return -1 ;
  234.         }
  235.       }
  236.       else
  237.       {
  238.      if ( e4type() != 'N' && e4type() != 'F' )
  239.      {
  240.         x4relate_error( relate_ptr, "(Relation Expression did not Return a Record Number)");
  241.         d4select(old_base) ;
  242.         return -1 ;
  243.      }
  244.  
  245.      rec_num =  (long) *((double *) ptr) ;
  246.  
  247.      rc =  d4go(rec_num) ;
  248.      if ( rc > 0 )
  249.         if ( x4miss( relate_ptr ) < 0)
  250.         {
  251.            d4select(old_base) ;
  252.            return -1 ;
  253.         }
  254.  
  255.      if ( rc < 0 )
  256.      {
  257.         d4select( old_base ) ;
  258.         return rc ;
  259.      }
  260.       }
  261.    }
  262.  
  263.    if ( (rc = x4relate_do()) < 0 )  return rc ;
  264.  
  265.    d4select( old_base ) ;
  266.    return 0 ;
  267. }
  268.  
  269.  
  270. x4go( long record_number )
  271. {
  272.    int rc ;
  273.  
  274.    if ( (rc =  d4go(record_number)) < 0 )  return rc ;
  275.    if ( (rc = x4relate_do()) < 0 )  return rc ;
  276.  
  277.    return rc ;
  278. }
  279.  
  280. static int  x4seek_key( char *, int ) ;
  281.  
  282. x4seek( char *search_string )
  283. {
  284.    int  rc ;
  285.  
  286.    if ( (rc = d4seek(search_string)) < 0 )  return rc ;
  287.    return( x4seek_key( search_string, rc) ) ;
  288. }
  289.  
  290. x4seek_str( char *search_string )
  291. {
  292.    int  rc ;
  293.  
  294.    if ( (rc = d4seek_str(search_string)) < 0 )  return rc ;
  295.    return( x4seek_key( search_string, rc) ) ;
  296. }
  297.  
  298. x4seek_double( double d )
  299. {
  300.    int  rc ;
  301.  
  302.    if ( (rc = d4seek_double(d)) < 0 )  return rc ;
  303.    return( x4seek_key( (char *) &d, rc) ) ;
  304. }
  305.  
  306. static int  x4seek_key( char *search_string, int rc1 )
  307. {
  308.    int     rc, index_ref, len ;
  309.    char *ptr ;
  310.  
  311.    if ( rc1 == 3 )
  312.    {
  313.       if ( (rc = x4relate_do()) < 0 )  return rc ;
  314.       return 3 ;
  315.    }
  316.  
  317.    if ( (rc = x4filter_do()) < rc )  return rc ;
  318.    if ( rc == 0 )
  319.    {
  320.       if ( (rc = x4relate_do()) < 0 )  return rc ;
  321.       return rc1 ;
  322.    }
  323.  
  324.    if ( (rc =  x4skip(1L)) != 0)  return rc ;  /* EOF or Error */
  325.  
  326.    /* Determine the Return Code */
  327.    index_ref =    d4ptr()->current_index ;
  328.    if ( index_ref < 0 )
  329.       index_ref =  d4ptr()->index_ref ;
  330.  
  331.    if ( (ptr =    i4eval( index_ref )) == (char *) 0 )  return -1 ;
  332.  
  333.    if ( e4type() == 'C' )
  334.    {
  335.       len =  (int) strlen(search_string) ;
  336.       if ( len > v4index[index_ref].key_len)  len = v4index[index_ref].key_len ;
  337.  
  338.       if ( memcmp(search_string, ptr, (size_t) len) != 0 )
  339.      rc =  2 ;
  340.       else
  341.       {
  342.       if ( len == v4index[index_ref].key_len )
  343.          rc =  0 ;
  344.       else
  345.          rc =  1 ;
  346.       }
  347.    }
  348.    else
  349.    {
  350.       if ( memcmp( ptr, search_string, (size_t) v4index[index_ref].key_len ) == 0 )
  351.      rc =  0 ;
  352.       else
  353.      rc =  2 ;
  354.    }
  355.  
  356.    return rc ;
  357. }
  358.  
  359. x4skip( long num_records )
  360. {
  361.    int     rc, rc2, is_eof ;
  362.    long  sign, good_rec ;
  363.  
  364.    good_rec =  d4recno() ;
  365.    if ( d4eof())
  366.       is_eof =  1 ;
  367.    else
  368.       is_eof =  0 ;
  369.  
  370.    if ( num_records < 0 )
  371.    {
  372.       sign =  -1L ;
  373.       num_records =  -num_records ;
  374.    }
  375.    else
  376.       sign =  1L ;
  377.  
  378.    rc =  0 ;
  379.  
  380.    while ( num_records--  &&  rc == 0 )
  381.    {
  382.       /* Skip One Record */
  383.       rc = d4skip(sign) ;
  384.       if ( rc < 0 )   return rc ;
  385.       if ( rc == 3 )  break ;
  386.       if ( rc == 1 )
  387.       {
  388.      if ((rc2 = x4filter_do()) < 0)  return -1 ;
  389.      if ( rc2 )
  390.      {
  391.         if ( is_eof )
  392.             {
  393.                rc =  3 ;
  394.                d4go(0L) ;
  395.                v4base[v4cur_base].eof =  1 ;
  396.             }
  397.             else
  398.         {
  399.            if ( (rc = x4go(good_rec)) != 0 )  return rc ;
  400.            rc =  1 ;
  401.         }
  402.         break ;
  403.      }
  404.      else
  405.         break ;
  406.       }
  407.  
  408.       for (;;)
  409.       {
  410.      if ((rc = x4filter_do()) < 0)    return rc ;
  411.      if ( rc == 0 )
  412.      {
  413.         good_rec =    d4recno() ;
  414.         break ;
  415.      }
  416.  
  417.      if ( (rc = d4skip(sign)) != 0)
  418.      {
  419.         if ( rc < 0 )  return rc ;
  420.         if ( rc == 3 )  break ;
  421.         if ( rc == 1 )
  422.         {
  423.            if ( is_eof )
  424.                {
  425.                   rc =  3 ;
  426.                   d4go(0L) ;
  427.                   v4base[v4cur_base].eof =  1 ;
  428.                }
  429.                else
  430.            {
  431.               if ( (rc = x4go(good_rec)) != 0 )  return rc ;
  432.               rc =  1 ;
  433.            }
  434.            break ;
  435.         }
  436.      }
  437.       }
  438.    }
  439.  
  440.    if ( (rc2 = x4relate_do()) < 0 )  return rc2 ;
  441.  
  442.    return rc ;
  443. }
  444.  
  445.  
  446. x4bottom()
  447. {
  448.    int    rc, rc2 ;
  449.  
  450.    if ( (rc =  d4bottom()) < 0 )  return rc ;
  451.    if ( rc == 0 )
  452.    {
  453.       if ((rc = x4filter_do()) < 0)  return rc ;
  454.       if ( rc )
  455.       {
  456.      if ((rc = x4skip(-1L)) < 0)  return rc ;
  457.      if ( rc )  return( x4skip(1L) ) ;
  458.       }
  459.    }
  460.  
  461.    if ( (rc2 = x4relate_do()) < 0 )  return rc2 ;
  462.  
  463.    return  rc ;
  464. }
  465.  
  466.  
  467. x4top()
  468. {
  469.    int    rc, rc2 ;
  470.  
  471.    if ( (rc =  d4top()) < 0)  return rc ;
  472.    if ( rc == 0 )
  473.    {
  474.       if ((rc = x4filter_do()) < 0)  return rc ;
  475.       if ( rc )  return( x4skip(1L) ) ;
  476.    }
  477.  
  478.    if ( (rc2 = x4relate_do()) < 0)  return rc2 ;
  479.  
  480.    return  rc ;
  481. }
  482.  
  483.  
  484. double    x4sum( long field_ref )
  485. {
  486.    double  total ;
  487.    int       rc, old_base ;
  488.  
  489.    total =  0.0 ;
  490.  
  491.    old_base =  d4select( -1 ) ;
  492.    d4select( (int) (field_ref >> 16) ) ;
  493.  
  494.    if ( (rc= x4top()) < 0 )
  495.    {
  496.       d4select( old_base ) ;
  497.       return 0.0 ;
  498.    }
  499.  
  500.    while ( rc != 3 )
  501.    {
  502.       total +=    f4value(field_ref) ;
  503.  
  504.       if ( (rc= x4skip(1L)) < 0 )
  505.       {
  506.      d4select( old_base ) ;
  507.      return 0.0 ;
  508.       }
  509.    }
  510.  
  511.    d4select( old_base ) ;
  512.  
  513.    return  total ;
  514. }
  515.  
  516.  
  517. int  x4insert( long rec_num )
  518. {
  519.    long  i_rec, count ;
  520.    BASE *base_ptr ;
  521.    int     index_ref, rc ;
  522.  
  523.    if ( (base_ptr =  d4ptr()) == (BASE *) 0)  return -1 ;
  524.    if ( (rc = d4lock(-1L, v4lock_wait)) < 0 )  return rc ;
  525.  
  526.    /* Temporarily Disable the Index Files */
  527.    index_ref =    base_ptr->index_ref ;
  528.    base_ptr->index_ref =  -1 ;
  529.  
  530.    /* Save the Current Record */
  531.    memcpy( base_ptr->old_buf,  base_ptr->buffer, (size_t) base_ptr->buffer_len ) ;
  532.  
  533.    for ( i_rec = count = d4reccount(); i_rec >= rec_num; i_rec-- )
  534.    {
  535.       if ( d4go(i_rec) < 0 )
  536.       {
  537.      base_ptr->index_ref =    index_ref ;
  538.      return -1 ;
  539.       }
  540.       if ( i_rec == count )
  541.       {
  542.          if ( d4append() < 0 )
  543.          {
  544.         base_ptr->index_ref = index_ref ;
  545.         return -1 ;
  546.          }
  547.       }
  548.       else
  549.          if ( d4write( i_rec+1 ) < 0 )
  550.          {
  551.         base_ptr->index_ref = index_ref ;
  552.         return -1 ;
  553.          }
  554.    }
  555.  
  556.    /* Restore the Saved Record */
  557.    memcpy ( base_ptr->buffer, base_ptr->old_buf, (size_t) base_ptr->buffer_len ) ;
  558.  
  559.    if ( d4write( rec_num ) < 0 )
  560.    {
  561.       base_ptr->index_ref =  index_ref ;
  562.       return -1 ;
  563.    }
  564.  
  565.    base_ptr->index_ref =  index_ref ;
  566.  
  567.    /* Reindex All of the Index Files */
  568.    if ( i4reindex( -1 ) < 0 )  return -1 ;
  569.  
  570.    if ( x4go(rec_num) < 0 )  return -1 ;
  571.  
  572.    return 0 ;
  573. }
  574.