/* t4unique.c (c)Copyright Sequiter Software Inc., 1990-1993. All rights reserved. */

/* Tests CodeBase unique entry code. */

#include "d4all.h"
#ifdef __TURBOC__
#pragma hdrstop
#endif

#include "t4test.h"

#ifndef S4INDEX_OFF

CODE4   cb;
DATA4  *data, *data2;
FIELD4 *c_field, *d_field, *n_field, *num, *char1, *char2 ;
TAG4   *tag ;
int count = 9 ;

static FIELD4INFO fields[] =
{
{ "N_FIELD", 'N', 8, 0 },
{ "C_FIELD", 'C', 8, 0 },
{ "D_FIELD", 'D', 8, 0 },
{ 0, 0,0,0 },
} ;

static TAG4INFO tags[] =
{
#ifdef N4OTHER
{ "N_TAG", "N_FIELD", "", r4unique_continue, 0 },
{ "C_TAG", "C_FIELD", "", r4unique_continue, 0 },
{ "D_TAG", "D_FIELD", "", r4unique_continue, 0 },
#else
{ "N_TAG", "N_FIELD", "", r4unique_continue, r4descending },
{ "C_TAG", "C_FIELD", "", r4unique_continue, r4descending },
{ "D_TAG", "D_FIELD", "", r4unique_continue, r4descending },
#endif
{ 0,0,0, 0, 0 },
} ;

static FIELD4INFO fields2[] =
{
{ "NUM", 'N', 8, 0 },
{ "CHAR1", 'C', 8, 0 },
{ "CHAR2", 'C', 8, 0 },
{ 0, 0,0,0 },
} ;

static TAG4INFO tags2[] =
{
{ "TAG1", "NUM", "", r4unique_continue, 0 },
{ "TAG2", "NUM", "", r4unique, 0 },

{ "TAG3", "NUM", ".NOT. DELETED()", r4unique_continue, 0 },
{ "TAG4", "NUM", ".NOT. DELETED()", r4unique, 0 },

{ "TAG5", "CHAR1", "", r4unique_continue, 0 },
{ "TAG6", "CHAR1", "", r4unique, 0 },

{ "TAG7", "CHAR1", ".NOT. DELETED()", r4unique_continue, 0 },
{ "TAG8", "CHAR1", ".NOT. DELETED()", r4unique, 0 },

{ "TAG9", "CHAR1+CHAR2", "", r4unique_continue, 0 },
{ "TAG10", "CHAR1+CHAR2", "", r4unique, 0 },

{ "TAG11", "CHAR1+CHAR2", ".NOT. DELETED()", r4unique_continue, 0 },
{ "TAG12", "CHAR1+CHAR2", ".NOT. DELETED()", r4unique, 0 },
{ 0,0,0, 0, 0 },
} ;

static int test_tag( D4DISPLAY *display )
{
#ifdef N4OTHER
  long r = 1 ;
#else
  long r = 9 ;
#endif

  if ( d4top( data ) != 0 )
    t4severe( t4err_go, "01" ) ;
  for ( ;; )
  {
    if ( d4eof( data ) )
      break ;
    if ( d4display_quit( display ) )
      return 1 ;

    if ( d4recno( data ) != r )
      t4severe( t4err_recno, "02" ) ;

#ifdef N4OTHER
    r += 2 ;
#else
    r -= 2 ;
#endif
    if ( d4skip( data, 1L ) < 0 )
      t4severe( t4err_skip, "03" ) ;
  }

  if ( d4go( data, 2L ) != 0 )
    t4severe( t4err_go, "04" ) ;

#ifndef N4OTHER
  if ( d4skip( data, 2L ) != r4eof )
#else
    if ( d4skip( data, 5 ) != r4eof )
#endif
      t4severe( t4err_skip, "05" ) ;

  return 0 ;
}

static int test_unique( D4DISPLAY *display, int do_open )
{
  long start_date, r ;
  char hold[10] ;
  start_date =  date4long( "19800101" ) ;

  cb.skip_error =  0 ;
  cb.safety =  0 ;

  if (do_open)
  {
    data = d4open( &cb, "T4UNIQUE" ) ;
    d4zap( data, 1L, d4reccount(data) ) ;
  }
  else
    data = d4create( &cb, "T4UNIQUE", fields, tags ) ;

  if ( data == 0 )
    t4severe( t4err_data, "06" ) ;

  d4opt_start( &cb ) ;

  c_field = d4field( data, "C_FIELD" ) ;
  d_field = d4field( data, "D_FIELD" ) ;
  n_field = d4field( data, "N_FIELD" ) ;
  if ( c_field == 0 || d_field == 0 || n_field == 0 )
    t4severe( t4err_field, "07" ) ;

  for ( r = 1; r <= 10; r++ )
  {
    if ( d4display_quit( display ) )
      return 1 ;

    if ( d4append_start(data, 0) < 0 )
      t4severe( t4err_append, "08" ) ;

    f4assign_long( n_field, (r+1)/2 ) ;
    f4assign_long( c_field, (r+1)/2 ) ;
    f4assign_long( d_field, start_date + (r+1)/2 ) ;

    if ( d4append(data) < 0 )
      t4severe( t4err_append, "09" ) ;
  }

  d4display_str( display,  "Testing using tags . . . ", 1 ) ;

  tag = d4tag( data, "N_TAG" ) ;
  if ( tag == 0 )
    t4severe( t4err_tag, "10" ) ;
  d4tag_select( data, tag ) ;
  if ( test_tag( display ) )
    return 1 ;

  if ( d4seek_double( data, 2.0 ) != 0 )
    t4severe( t4err_seek, "11" ) ;
  if ( d4recno( data ) != 3 )
    t4severe( t4err_recno, "12" ) ;

  tag = d4tag( data, "D_TAG" ) ;
  if ( tag == 0 )
    t4severe( t4err_tag, "13" ) ;
  d4tag_select( data, tag ) ;
  if ( test_tag( display ) )
    return 1 ;

  tag = d4tag( data, "C_TAG" ) ;
  if ( tag == 0 )
    t4severe( t4err_tag, "14" ) ;
  d4tag_select( data, tag ) ;
  if ( test_tag( display ) )
    return 1 ;

  if ( d4reindex( data ) != 0 )
    t4severe( t4err_reindex, "15" ) ;

  tag = d4tag( data, "N_TAG" ) ;
  if ( tag == 0 )
    t4severe( t4err_tag, "16" ) ;
  d4tag_select( data, tag ) ;
  if ( test_tag( display ) )
    return 1 ;

  tag = d4tag( data, "D_TAG" ) ;
  if ( tag == 0 )
    t4severe( t4err_tag, "17" ) ;
  d4tag_select( data, tag ) ;
  if ( test_tag( display ) )
    return 1 ;

  tag = d4tag( data, "C_TAG" ) ;
  if ( tag == 0 )
    t4severe( t4err_tag, "18" ) ;
  d4tag_select( data, tag ) ;
  if ( test_tag( display ) )
    return 1 ;

#ifndef N4OTHER
  if (do_open)
  {
    data2 = d4open( &cb, "T4UNIQU2" ) ;
    if ( data2 == 0 )
      t4severe( t4err_data, "19" ) ;

    for ( r = 0, tag = 0; r < 6; r++ ) /* set every second tag.unique_error to r4unique */
    {
      tag = d4tag_next( data2 , d4tag_next( data2, tag ) ) ;
      if ( tag == 0 )
        t4severe( t4err_tag, "20" ) ;
      tag->unique_error = r4unique ;
    }

    if ( d4zap( data2, 6L, d4reccount( data2 ) ) != 0 ) /* delete half the records */
      t4severe( t4err_zap, "21" ) ;
    count -= 5 ;       /* set count so that append adds zapped records back */
    if ( d4check( data2 ) != 0 )
      t4severe( t4err_check, "22" ) ;
  }
  else
  {
    d4display_str( display,  "T4UNIQUE: Part two . . . ", 1 ) ;
    data2 = d4create( &cb, "T4UNIQU2", fields2, tags2 ) ;
    if ( data2 == 0 )
      t4severe( t4err_data, "23" ) ;
  }

  num = d4field( data2, "NUM" ) ;
  char1 = d4field( data2, "CHAR1" ) ;
  char2 = d4field( data2, "CHAR2" ) ;
  if ( num == 0 || char1 == 0 || char2 == 0 )
    t4severe( t4err_field, "24" ) ;

  for ( r = count; r >= 0; r-- )
  {
    if ( d4display_quit( display ) )
      return 1 ;

    if ( d4append_start( data2, 0) < 0 )
      t4severe( t4err_append, "25" ) ;

    f4assign_long( num, (r*100000+24689) ) ;
    c4ltoa45( (r*100000+24689), hold, 8 ) ;
    f4assign( char1, hold ) ;
    c4ltoa45( (r*100000+24689), hold, 8 ) ;
    f4assign( char2, hold ) ;

    if ( d4append( data2 ) < 0 )
      t4severe( t4err_append, "26" ) ;
  }

  if ( d4check( data2 ) != 0 )
    t4severe( t4err_check, "27" ) ;

  tag = d4tag( data2, "TAG6" ) ;
  if ( tag == 0 )
    t4severe( t4err_tag, "28" ) ;
  d4tag_select( data2, tag ) ;

  if ( d4go( data2, 2L ) != 0 )
    t4severe( t4err_go, "29" ) ;
  f4assign( char1, "  724689" ) ;     /* create non-unique key situation */
  if ( d4flush( data2 ) != r4unique )
    t4severe( t4err_flush, "30" ) ;
  data2->record_changed = 0 ; /* replace with d4abort_change */

  if ( d4seek( data2, "  824689" ) )  /* check that no change made to tag */
    t4severe( t4err_seek, "31" ) ;

  if ( memcmp( f4ptr( char1 ), "  824689", 8 ) ) /* check record unchanged */
    t4severe( t4err_field, "32" ) ;

  if ( d4check( data2 ) != 0 )
    t4severe( t4err_check, "33" ) ;

  tag = d4tag( data2, "TAG2" ) ; /* check that previous tags not updated */
  if ( tag == 0 )
    t4severe( t4err_tag, "34" ) ;
  d4tag_select( data2, tag ) ;
  if ( d4seek_double( data2, 724689.0 ) )
    t4severe( t4err_seek, "35" ) ;
  if ( d4seek( data2, "724689" ) )
    t4severe( t4err_seek, "36" ) ;

  if ( d4append_start( data2, 0 ) != 0 )
    t4severe( t4err_append, "37" ) ;
  f4assign_long( num, 99999999 ) ;
  f4assign( char1, "99999999" ) ;
  f4assign( char2, "99999999" ) ;
  if ( d4append_start( data2, 0 ) != 0 )
    t4severe( t4err_append, "38" ) ;
  if ( d4flush( data2 ) != 0 )
    t4severe( t4err_flush, "39" ) ;

  if ( d4seek_double( data2, 99999999.0 ) != r4eof )  /* check that no change made to tag */
    t4severe( t4err_seek, "40" ) ;

  if ( d4check( data2 ) != 0 )
    t4severe( t4err_check, "41" ) ;
#endif

  if ( d4close_all( &cb ) < 0 )
    t4severe( t4err_close, "42" ) ;
  return 0 ;
}


static int  test_with_mem_check( D4DISPLAY *display )
{
  d4init( &cb ) ;

  cb.hWnd = (unsigned) display->hWnd ;
#ifdef S4DLL
  cb.hInst = (unsigned) display->hInst ;
#endif

  if ( test_unique( display, 0 ) )
    return 1 ;
  if ( test_unique( display, 1 ) )
    return 1 ;

#ifndef S4TEST_KEEP_FILES
  u4remove( "T4UNIQUE.dbf" ) ;
  u4remove( "T4UNIQU2.dbf" ) ;
#ifdef N4OTHER
  u4remove( "T4UNIQUE.CGP" ) ;
  u4remove( "T4UNIQU2.CGP" ) ;
#endif
#ifdef S4MDX
  u4remove( "T4UNIQUE.mdx" ) ;
  u4remove( "T4UNIQU2.mdx" ) ;
#endif
#ifdef S4FOX
  u4remove( "T4UNIQUE.cdx" ) ;
  u4remove( "T4UNIQU2.cdx" ) ;
#endif
#ifdef S4CLIPPER
  u4remove( "N_TAG.NTX" ) ;
  u4remove( "C_TAG.NTX" ) ;
  u4remove( "D_TAG.NTX" ) ;
  u4remove( "TAG1.NTX" ) ;
  u4remove( "TAG2.NTX" ) ;
  u4remove( "TAG3.NTX" ) ;
  u4remove( "TAG4.NTX" ) ;
  u4remove( "TAG5.NTX" ) ;
  u4remove( "TAG6.NTX" ) ;
  u4remove( "TAG7.NTX" ) ;
  u4remove( "TAG8.NTX" ) ;
  u4remove( "TAG9.NTX" ) ;
  u4remove( "TAG10.NTX" ) ;
  u4remove( "TAG11.NTX" ) ;
  u4remove( "TAG12.NTX" ) ;
#endif
#ifdef S4NDX
  u4remove( "N_TAG.NDX" ) ;
  u4remove( "C_TAG.NDX" ) ;
  u4remove( "D_TAG.NDX" ) ;
  u4remove( "TAG1.NDX" ) ;
  u4remove( "TAG2.NDX" ) ;
  u4remove( "TAG3.NDX" ) ;
  u4remove( "TAG4.NDX" ) ;
  u4remove( "TAG5.NDX" ) ;
  u4remove( "TAG6.NDX" ) ;
  u4remove( "TAG7.NDX" ) ;
  u4remove( "TAG8.NDX" ) ;
  u4remove( "TAG9.NDX" ) ;
  u4remove( "TAG10.NDX" ) ;
  u4remove( "TAG11.NDX" ) ;
  u4remove( "TAG12.NDX" ) ;
#endif
#endif

  d4init_undo(&cb) ;
  mem4reset() ;

#ifdef S4DEBUG
  mem4check_memory() ;

#ifndef S4DLL
  if ( mem4free_check(100) != 0 )
    t4severe( t4err_memory, "43" ) ;
#endif
#endif

  return 0 ;
}

#endif

int  S4FUNCTION t4test( D4DISPLAY *display )
{
#ifdef S4INDEX_OFF
  display->y += 2 ;
  d4display_str( display, "T4GROUP:   REQUIRES INDEXING (S4INDEX_OFF DEFINED)", 1) ;
  d4display_str( display, "", 1) ;
  return 1 ;
#else
  d4display_str( display,  "T4UNIQUE Test  ", 1 ) ;
  d4display_str( display,  " ", 1 ) ;

  if ( test_with_mem_check( display ) )
    e4exit(&cb) ;

  display->y += 2 ;
  d4display_str( display, "T4UNIQUE:   SUCCESS", 1) ;
#endif
  return 1 ;
}