home *** CD-ROM | disk | FTP | other *** search
- /* x4.c (c)Copyright Sequiter Software Inc., 1987-1990. All rights reserved. */
-
- #include "d4all.h"
- #include "u4error.h"
- #include "p4misc.h"
-
- #include <stdlib.h>
- #include <string.h>
-
- extern BASE *v4base ;
- extern INDEX *v4index ;
- extern int v4cur_base, v4lock_wait ;
-
- extern X4FILTER *v4filter ;
- extern X4RELATE *v4relate ;
-
-
- #ifdef KR
- int x4filter( filter_routine )
- int (*filter_routine)() ;
- #else
- int x4filter( int (*filter_routine)(void) )
- #endif
- {
- BASE *base_ptr ;
-
- base_ptr = d4ptr() ;
- if ( base_ptr == (BASE *) 0 ) return -1 ; /* No Database is Selected */
-
- if ( v4filter == (X4FILTER *) 0 )
- if ( h4create( (char **) &v4filter, 5, sizeof(X4FILTER), 3 ) < 0 ) return -1 ;
-
- base_ptr->filter_ref = h4get( (char **) &v4filter, base_ptr->filter_ref ) ;
- if ( base_ptr->filter_ref < 0 ) return -1 ;
-
- v4filter[base_ptr->filter_ref].filter_routine = filter_routine ;
-
- return 0 ;
- }
-
-
- x4blank() /* Returns TRUE if the record is blank */
- {
- char *ptr ;
- int i ;
-
- for ( i= 1; i<= f4num_fields(); i++ )
- {
- ptr = f4str( f4j_ref(i) ) ;
- while ( *ptr != (char) 0 )
- if ( *ptr++ != ' ' ) return 0 ;
- }
-
- return 1 ;
- }
-
-
-
- int x4filter_do()
- {
- int on, rc ;
- BASE *base_ptr ;
-
- if (v4filter == (X4FILTER *) 0) return 0 ;
-
- base_ptr = d4ptr() ;
- if ( base_ptr == (BASE *) 0) return -1 ;
-
- for ( on = base_ptr->filter_ref; on >= 0; on = v4filter[on].prev)
- {
- rc = (*v4filter[on].filter_routine)() ;
- if ( rc < 0 ) return -1 ;
- if ( rc > 0 ) return 1 ;
- }
-
- return 0 ;
- }
-
-
- x4relate( char *expr, int base_ref, int index_ref, long miss_code )
- {
- BASE *base_ptr ;
- X4RELATE *relate_ptr ;
- char *compile_ptr ;
-
- base_ptr = d4ptr() ;
- if ( base_ptr == (BASE *) 0 )
- {
- u4error( E_CONTROL, (char *) 0 ) ;
- return -1 ; /* No Database is Selected */
- }
-
- if ( base_ref == v4cur_base )
- {
- u4error( E_RELATED, (char *) 0 ) ;
- return -1 ; /* No Database is Selected */
- }
-
- if ( e4parse( expr, &compile_ptr ) < 0 ) return -1 ;
- if ( e4exec( compile_ptr ) == (char *) 0 )
- {
- h4free_memory( compile_ptr ) ;
- return -1 ;
- }
-
- if ( v4relate == (X4RELATE *) 0 )
- if ( h4create( (char **) &v4relate, 5, sizeof(X4RELATE), 3 ) < 0 ) return -1 ;
-
- base_ptr->relate_ref = h4get( (char **) &v4relate, base_ptr->relate_ref);
- if ( base_ptr->relate_ref < 0 ) return -1 ;
-
- relate_ptr = v4relate + base_ptr->relate_ref ;
-
- relate_ptr->control_base_ref = d4select( -1 ) ;
-
- if ( index_ref >= 0 )
- base_ref = v4index[index_ref].base_ref ;
-
- relate_ptr->compile = compile_ptr ;
- relate_ptr->base_ref = base_ref ;
- relate_ptr->index_ref = index_ref ;
- relate_ptr->miss_code = miss_code ;
-
- return 0 ;
- }
-
- static void x4relate_error( X4RELATE *, char *) ;
-
- static void x4relate_error( X4RELATE *relate_ptr, char *msg )
- {
- char rec_str[34], *index_file ;
-
- d4select( relate_ptr->control_base_ref ) ;
-
- c4ltoa( d4recno(), rec_str, 8 ) ;
- rec_str[8] = '\000' ;
-
- if ( relate_ptr->index_ref >= 0 )
- index_file = v4index[relate_ptr->index_ref].name ;
- else
- index_file = "No Index File" ;
-
- u4error( E_RELATING, msg,
- "Controlling Database:",
- v4base[relate_ptr->control_base_ref].name,
- "On Record Number: ", rec_str,
- "Related Database:", v4base[relate_ptr->base_ref].name,
- "Index File:", index_file,
- (char *) 0 ) ;
- }
-
- static int x4miss( X4RELATE * ) ;
-
- static x4miss( X4RELATE *relate_ptr )
- {
- if ( relate_ptr->miss_code >= 1 )
- {
- if ( d4go( relate_ptr->miss_code ) < 0)
- {
- d4select( relate_ptr->control_base_ref ) ;
- return -1 ;
- }
- return 0 ;
- }
-
- memset( v4base[relate_ptr->base_ref].buffer, (int) ' ',
- (size_t) v4base[relate_ptr->base_ref].buffer_len ) ;
- v4base[relate_ptr->base_ref].rec_num = -1L ;
- if ( relate_ptr->miss_code != 0 )
- {
- x4relate_error( relate_ptr, "(No Record Located)" ) ;
- return -1 ;
- }
-
- return 0 ;
- }
-
-
- x4relate_do()
- {
- int on, old_base, rc, old_index ;
- long rec_num ;
- char *ptr ;
- X4RELATE *relate_ptr ;
-
- if ( (on = d4ptr()->relate_ref) < 0 ) return 0 ;
-
- old_base = d4select( -1 ) ;
-
- for ( ; on >= 0; on = relate_ptr->prev )
- {
- relate_ptr = v4relate + on ;
-
- if ( (ptr = (char *) e4exec(relate_ptr->compile)) == (char *) 0 )
- {
- d4select(old_base) ;
- return -1 ;
- }
-
- d4select( relate_ptr->base_ref ) ;
- if ( relate_ptr->base_ref != v4cur_base )
- {
- x4relate_error( relate_ptr, "(Could not Select Related Database)");
- d4select(old_base) ;
- return -1 ;
- }
-
- if ( relate_ptr->index_ref >= 0 )
- {
- old_index = d4ptr()->current_index ;
-
- i4select( relate_ptr->index_ref ) ;
- if ( i4seek_ref() != relate_ptr->index_ref)
- {
- x4relate_error( relate_ptr, "(Could not Select Related Index File)" ) ;
- d4select(old_base) ;
- return -1 ;
- }
-
- rc = d4seek( ptr ) ;
- i4select( old_index ) ;
-
- if ( rc < 0 )
- {
- d4select(old_base) ;
- return rc ;
- }
-
- if ( rc > 1 )
- if ( x4miss( relate_ptr ) < 0)
- {
- d4select(old_base) ;
- return -1 ;
- }
- }
- else
- {
- if ( e4type() != 'N' && e4type() != 'F' )
- {
- x4relate_error( relate_ptr, "(Relation Expression did not Return a Record Number)");
- d4select(old_base) ;
- return -1 ;
- }
-
- rec_num = (long) *((double *) ptr) ;
-
- rc = d4go(rec_num) ;
- if ( rc > 0 )
- if ( x4miss( relate_ptr ) < 0)
- {
- d4select(old_base) ;
- return -1 ;
- }
-
- if ( rc < 0 )
- {
- d4select( old_base ) ;
- return rc ;
- }
- }
- }
-
- if ( (rc = x4relate_do()) < 0 ) return rc ;
-
- d4select( old_base ) ;
- return 0 ;
- }
-
-
- x4go( long record_number )
- {
- int rc ;
-
- if ( (rc = d4go(record_number)) < 0 ) return rc ;
- if ( (rc = x4relate_do()) < 0 ) return rc ;
-
- return rc ;
- }
-
- static int x4seek_key( char *, int ) ;
-
- x4seek( char *search_string )
- {
- int rc ;
-
- if ( (rc = d4seek(search_string)) < 0 ) return rc ;
- return( x4seek_key( search_string, rc) ) ;
- }
-
- x4seek_str( char *search_string )
- {
- int rc ;
-
- if ( (rc = d4seek_str(search_string)) < 0 ) return rc ;
- return( x4seek_key( search_string, rc) ) ;
- }
-
- x4seek_double( double d )
- {
- int rc ;
-
- if ( (rc = d4seek_double(d)) < 0 ) return rc ;
- return( x4seek_key( (char *) &d, rc) ) ;
- }
-
- static int x4seek_key( char *search_string, int rc1 )
- {
- int rc, index_ref, len ;
- char *ptr ;
-
- if ( rc1 == 3 )
- {
- if ( (rc = x4relate_do()) < 0 ) return rc ;
- return 3 ;
- }
-
- if ( (rc = x4filter_do()) < rc ) return rc ;
- if ( rc == 0 )
- {
- if ( (rc = x4relate_do()) < 0 ) return rc ;
- return rc1 ;
- }
-
- if ( (rc = x4skip(1L)) != 0) return rc ; /* EOF or Error */
-
- /* Determine the Return Code */
- index_ref = d4ptr()->current_index ;
- if ( index_ref < 0 )
- index_ref = d4ptr()->index_ref ;
-
- if ( (ptr = i4eval( index_ref )) == (char *) 0 ) return -1 ;
-
- if ( e4type() == 'C' )
- {
- len = (int) strlen(search_string) ;
- if ( len > v4index[index_ref].key_len) len = v4index[index_ref].key_len ;
-
- if ( memcmp(search_string, ptr, (size_t) len) != 0 )
- rc = 2 ;
- else
- {
- if ( len == v4index[index_ref].key_len )
- rc = 0 ;
- else
- rc = 1 ;
- }
- }
- else
- {
- if ( memcmp( ptr, search_string, (size_t) v4index[index_ref].key_len ) == 0 )
- rc = 0 ;
- else
- rc = 2 ;
- }
-
- return rc ;
- }
-
- x4skip( long num_records )
- {
- int rc, rc2, is_eof ;
- long sign, good_rec ;
-
- good_rec = d4recno() ;
- if ( d4eof())
- is_eof = 1 ;
- else
- is_eof = 0 ;
-
- if ( num_records < 0 )
- {
- sign = -1L ;
- num_records = -num_records ;
- }
- else
- sign = 1L ;
-
- rc = 0 ;
-
- while ( num_records-- && rc == 0 )
- {
- /* Skip One Record */
- rc = d4skip(sign) ;
- if ( rc < 0 ) return rc ;
- if ( rc == 3 ) break ;
- if ( rc == 1 )
- {
- if ((rc2 = x4filter_do()) < 0) return -1 ;
- if ( rc2 )
- {
- if ( is_eof )
- {
- rc = 3 ;
- d4go(0L) ;
- v4base[v4cur_base].eof = 1 ;
- }
- else
- {
- if ( (rc = x4go(good_rec)) != 0 ) return rc ;
- rc = 1 ;
- }
- break ;
- }
- else
- break ;
- }
-
- for (;;)
- {
- if ((rc = x4filter_do()) < 0) return rc ;
- if ( rc == 0 )
- {
- good_rec = d4recno() ;
- break ;
- }
-
- if ( (rc = d4skip(sign)) != 0)
- {
- if ( rc < 0 ) return rc ;
- if ( rc == 3 ) break ;
- if ( rc == 1 )
- {
- if ( is_eof )
- {
- rc = 3 ;
- d4go(0L) ;
- v4base[v4cur_base].eof = 1 ;
- }
- else
- {
- if ( (rc = x4go(good_rec)) != 0 ) return rc ;
- rc = 1 ;
- }
- break ;
- }
- }
- }
- }
-
- if ( (rc2 = x4relate_do()) < 0 ) return rc2 ;
-
- return rc ;
- }
-
-
- x4bottom()
- {
- int rc, rc2 ;
-
- if ( (rc = d4bottom()) < 0 ) return rc ;
- if ( rc == 0 )
- {
- if ((rc = x4filter_do()) < 0) return rc ;
- if ( rc )
- {
- if ((rc = x4skip(-1L)) < 0) return rc ;
- if ( rc ) return( x4skip(1L) ) ;
- }
- }
-
- if ( (rc2 = x4relate_do()) < 0 ) return rc2 ;
-
- return rc ;
- }
-
-
- x4top()
- {
- int rc, rc2 ;
-
- if ( (rc = d4top()) < 0) return rc ;
- if ( rc == 0 )
- {
- if ((rc = x4filter_do()) < 0) return rc ;
- if ( rc ) return( x4skip(1L) ) ;
- }
-
- if ( (rc2 = x4relate_do()) < 0) return rc2 ;
-
- return rc ;
- }
-
-
- double x4sum( long field_ref )
- {
- double total ;
- int rc, old_base ;
-
- total = 0.0 ;
-
- old_base = d4select( -1 ) ;
- d4select( (int) (field_ref >> 16) ) ;
-
- if ( (rc= x4top()) < 0 )
- {
- d4select( old_base ) ;
- return 0.0 ;
- }
-
- while ( rc != 3 )
- {
- total += f4value(field_ref) ;
-
- if ( (rc= x4skip(1L)) < 0 )
- {
- d4select( old_base ) ;
- return 0.0 ;
- }
- }
-
- d4select( old_base ) ;
-
- return total ;
- }
-
-
- int x4insert( long rec_num )
- {
- long i_rec, count ;
- BASE *base_ptr ;
- int index_ref, rc ;
-
- if ( (base_ptr = d4ptr()) == (BASE *) 0) return -1 ;
- if ( (rc = d4lock(-1L, v4lock_wait)) < 0 ) return rc ;
-
- /* Temporarily Disable the Index Files */
- index_ref = base_ptr->index_ref ;
- base_ptr->index_ref = -1 ;
-
- /* Save the Current Record */
- memcpy( base_ptr->old_buf, base_ptr->buffer, (size_t) base_ptr->buffer_len ) ;
-
- for ( i_rec = count = d4reccount(); i_rec >= rec_num; i_rec-- )
- {
- if ( d4go(i_rec) < 0 )
- {
- base_ptr->index_ref = index_ref ;
- return -1 ;
- }
- if ( i_rec == count )
- {
- if ( d4append() < 0 )
- {
- base_ptr->index_ref = index_ref ;
- return -1 ;
- }
- }
- else
- if ( d4write( i_rec+1 ) < 0 )
- {
- base_ptr->index_ref = index_ref ;
- return -1 ;
- }
- }
-
- /* Restore the Saved Record */
- memcpy ( base_ptr->buffer, base_ptr->old_buf, (size_t) base_ptr->buffer_len ) ;
-
- if ( d4write( rec_num ) < 0 )
- {
- base_ptr->index_ref = index_ref ;
- return -1 ;
- }
-
- base_ptr->index_ref = index_ref ;
-
- /* Reindex All of the Index Files */
- if ( i4reindex( -1 ) < 0 ) return -1 ;
-
- if ( x4go(rec_num) < 0 ) return -1 ;
-
- return 0 ;
- }
-