

/* Here is a program template to use when you need to write a program to     */
/* change an ISAM file's record length, or a field's offset or length (or,   */
/* indeed, anything that cannot be done with ReIndex), and you already have  */
/* lots of records stored and DON'T want to re-key all that data...          */

/* To do this, make a specs file for the new file information (different     */
/* file names, please!), create the ISAM file, and use this program (suit-   */
/* ably modified to work with your records and needs) to read records from   */
/* the old file, transfer info from the old record to the new record, and    */
/* store the new record in the new file.                                     */

/* NOTE: we do not lock the records read from the old file or stored in the  */
/* new file, as we have locked both files with exclusive locks.              */

#include <MYLIB:ISAMLibPROTO.c>

void main ( int argc, char *(argv[]) );

#define OLDSPECSFILENAME   /* insert OLD specs file name here in quotes */
#define NEWSPECSFILENAME   /* insert NEW specs file name here in quotes */


struct OldRecord {
}

struct NewRecord {
}

ULONG OldISAMHandle = 0L, NewISAMHandle = 0L;
long ErrorCode;
struct Library *ISAMBase = NULL;


/*---------------------------------- StartUp --------------------------------*/
BOOL StartUp ( void )
{
  if ( (ISAMBase = OpenLibrary ( "isam.library", 0 )) == NULL )
    {
      printf ( "\nCouldn't open ISAM library.\n\n" );
      return ( FALSE );
    }
  if (( ErrorCode = OpenISAMFile ( OLDSPECSFILENAME,
                                   TRUE, 'W', FALSE, &OldISAMHandle )) != OK )
    {
      printf ( "Error %ld encountered opening old file.\n", ErrorCode );
      return ( FALSE );
    }
  if (( ErrorCode = OpenISAMFile ( NEWSPECSFILENAME,
                                   TRUE, 'W', FALSE, &NewISAMHandle )) != OK )
    {
      printf ( "Error %ld encountered opening new file.\n", ErrorCode );
      return ( FALSE );
    }

  return (TRUE );
}


/*---------------------------------- ShutDown -------------------------------*/
void ShutDown ( void )
{

  if ( ISAMBase && ISAM )
    {
      if ( OldISAMHandle != 0L )
        {
          (void) UnLockISAMFile ( OldISAMHandle );
          (void) CloseISAMFile  ( OldISAMHandle );
        }
      if ( NewISAMHandle != 0L )
        {
          (void) UnLockISAMFile ( NewISAMHandle );
          (void) CloseISAMFile  ( NewISAMHandle );
        }
    }

  if ( ISAMBase )
    CloseLibrary ( ISAMBase );

  return;
}


/************************************ main ************************************/
void main ( argc, argv )
int argc;
char * (argv []);

{
  struct OldRecord OldRec;
  struct NewRecord NewRec;
  ULONG OldRecNo, NewRecNo, ul;
  

/* modify the following to handle whatever arguments you wish. */

  switch ( argc )
  {
    case 0 : 

    case 2 : if ( argv[1][0] != '?' )
               break;

    default: printf ( "\nFORMAT: '%s'\n\n", argv[0] );
             exit ( 5 );
  }

  if ( !StartUp () )
    {
      ShutDown ();
      exit ( 5 );
    }

  printf ( "\n\nBeginning File Conversion...\n\n" );

  for ( ul = 0L; ; ul++ )
  {
    printf ( "Processing Record #%lu.\r", ul );

    ErrorCode = ReadISAMRecord ( OldISAMHandle, ul, FALSE, ' ', &OldRec );

    switch ( ErrorCode )
    {
      case ERROR_DELETED_RECORD
              : continue;

      case ERROR_RECORD_TOO_HIGH
              : break;

      case OK : if ( some_quality_we_don't_want )
                  continue;
                break;
 
      default : printf ( "Error %ld encountered reading old record #%lu.\n",
                         ErrorCode, ul );
                break;
    }
    if ( ErrorCode != OK )
      break;

        /* OK, we've got the old record, now transfer the contents    */
        /* to the new record, making any changes/additions/deletions  */
        /* you want to get the new record just right.                 */
        /* Keep in mind that if you are changing a repeatable key to  */
        /* a unique key, that you'll have to add something here to    */
        /* keep from attempting to store more than one with the same  */
        /* key value.   Of course, if you want to just eliminate all  */
        /* but the first value encountered, you could just add a case */
        /* ERROR_RECORD_ALREADY_EXISTS : continue to the above switch.*/

    {
       /* ...stuff to put old record stuff into new record... */
    }

    if (( ErrorCode = StoreISAMRecord ( NewISAMHandle, &NewRec,
                                        FALSE, ' ', &NewRecNo )) != OK )
      {
        printf ( "Error %ld encountered storing changed old record #%lu.\n",
                  ErrorCode, ul );
        break;
      }

    continue;    
  }


  printf ( "\n\nFile conversion complete.\n\n" );

  ShutDown ();

  exit ( 0 );
}
