  | 
»  | 
 | 
  
 | 
 | 
The following example program shows how a KSAM XL file can be created, accessed, and updated from an HP C/iX program.  This program uses features of ANSI C. Compile with INFO=-Aa + e. This example program uses the assert macro to do quick error checking.  In a production program, more comprehensive error checking and reporting would be desirable. The KSAM XL file has the following layout:
 
 1 - 5  Employee number         (primary key)
 6 - 25 Name                        (secondary key)
26 - 34 Social Security Number
35 - 38 Department Number     (secondary key)
39 - 44 Date of hire
  
 
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mpe.h>:
#pragma intrinsic FCLOSE, FFINDN, FLOCK
#pragma intrinsic FREAD, FREADBYKEY, FREMOVE
#pragma intrinsic FUNLOCK, FUPDATE, FWRITE
#pragma intrinsic HPCICOMMAND, HPFOPEN
#define FILENAME "KSAMD"
typedef char record_t[44];
static int filenum;
static void close_file(void);
static void create_file(void);
static void delete_records(void);
static void dump_file(void);
static void list_sequential(void);
static void list_sequential_primary(void);
static void list_sequential_secondary(int location);
static void lock_file(void);
static void open_file(void);
static void unlock_file(void);
static void update_records(void);
static void write_new_records(void);
static void write_record(const char *record);
main(void)
{
   create_file();
   open_file();
   dump_file();
   write_new_records();
   update_records();
   delete_records();
   dump_file();
   close_file();
   return EXIT_SUCCESS;
}
static void close_file(void)
{
   /* Close file */
   FCLOSE(filenum, 0, 0);
   assert(ccode()==CCE);
}
static void create_file(void)
{
   /* Create sample KSAM XL file and load initial test data */
   int status; short cmderror;
   const int ksamxl=3, out=1, recsize=sizeof(record_t),
       filesize=100, save=1, ascii=1;
   const struct
      {
      short filler_1[10];
      unsigned short language_id      : 16;
      short filler_2[4];
      struct
         {
         unsigned short filler_1      : 10;
         unsigned short chg_primary   : 1;
         unsigned short kslang        : 1;
         unsigned short ksreuse       : 1;
         unsigned short seq_random    : 1;
         unsigned short rec_numbering : 1;
         unsigned short filler_2      : 1;
         } flagword;
      unsigned short filler_3         : 8;
      unsigned short num_keys         : 8;
      struct
         {
         unsigned short key_type      : 4;
         unsigned short key_length    : 12;
         unsigned short key_location  : 16;
         unsigned short dflag         : 1;
         unsigned short filler_1      : 15;
         unsigned short filler_2      : 8;
         unsigned short rflag         : 1;
         unsigned short filler_3      : 7;
         } keyparms[16];
      } ksamparam = { {0}, 0, {0}, {0,0,1,0,0,0,0}, 0, 3,
                      { {1, 5, 1,0,0,0,0,0},
                        {1,20, 6,1,0,0,0,0},
                        {1, 4,35,1,0,0,0,0} } };
   const record_t test_data[] =
      {
      "11111DOE JOHN            1230067898540821201",
      "03452CUSTER HERB         3218800003160821203",
      "28766WORKMAN DEBBIE      0006612341520850601",
      "33678MORSE EUGENE        8760098763160850715"
      } ;
   const int test_items = sizeof test_data / sizeof test_data[0];
   int i;
   /* First, purge file if it already exists */
   HPCICOMMAND("PURGE " FILENAME "\r", &cmderror, , 2);
   assert(!cmderror || cmderror==-383);
   /* Create new KSAM XL file, output access, 44-byte
      ASCII records, limit = 100, save disposition */
   HPFOPEN(&filenum, &status,
            2, "-" FILENAME "-",
           10, &ksamxl,
           11, &out,
           19, &recsize,
           35, &filesize,
           50, &save,
           53, &ascii,
           54, &ksamparam);
   assert(!status);
   /* Write test data to file */
   for (i=0; i<test_items; ++i)
      write_record(test_data[i]);
   printf("\n");
   /* Close file */
   FCLOSE(filenum, 0, 0);
   assert(ccode()==CCE);
}
static void delete_records(void)
{
   /* Delete records for several employees */
   const char delete_data[][5] = {"33678", "03452"};
   const int delete_items =
      sizeof delete_data / sizeof delete_data[0];
   int i;
   record_t buffer;
   for (i=0; i<delete_items; ++i)
      {
      printf("Deleting employee %.5s:  ", delete_data[i]);
      lock_file();
      FREADBYKEY(filenum, buffer, - sizeof buffer,
                 delete_data[i], 0);
      assert(ccode()==CCE);
      printf("%.20s\n", buffer+5);
      FREMOVE(filenum);
      assert(ccode()==CCE);
      unlock_file();
      }
   printf("\n");
}
static void dump_file(void)
{
   /* List the file several different ways */
   list_sequential_primary();
   list_sequential_secondary(6);
   list_sequential_secondary(35);
}
static void list_sequential(void)
{
   /* List the file, looping on FREAD until end-of-data */
   int save_ccode;
   record_t buffer;
   for (;;)
      {
      FREAD(filenum, buffer, - sizeof buffer);
      if ((save_ccode=ccode()) == CCG)
         break;
      assert(save_ccode==CCE);
      printf("     %.5s   %.20s   %.3s-%.2s-%.4s   "
             "%.4s   %.2s/%.2s/%.2s\n",
             buffer, buffer+5, buffer+25, buffer+28, buffer+30,
             buffer+34, buffer+40, buffer+42, buffer+38);
      }
   printf("\n");
}
static void list_sequential_primary(void)
{
   /* List file in sequence on primary key */
   printf("In sequence by primary key:\n");
   lock_file();
   /* Following call to FFINDN not necessary if this
      is the first access since the file was opened */
   FFINDN(filenum, -1, 0);
   assert(ccode()==CCE);
   list_sequential();
   unlock_file();
}
static void list_sequential_secondary(const int location)
{
   /* List file in sequence on specified secondary key */
   printf("In sequence by secondary key in location %d:\n",
          location);
   lock_file();
   FFINDN(filenum, -1, location);
   assert(ccode()==CCE);
   list_sequential();
   unlock_file();
}
static void lock_file(void)
{
   /* Lock the file unconditionally */
   FLOCK(filenum, 1);
   assert(ccode()==CCE);
}
static void open_file(void)
{
   /* Open file for shared update access with locking */
   int status;
   const int old=1, update=5, lock=1, shr=3;
   HPFOPEN(&filenum, &status,
            2, "-" FILENAME "-",
            3, &old,
           11, &update,
           12, &lock,
           13, &shr);
   assert(!status);
}
static void unlock_file(void)
{
   /* Unlock the file */
   FUNLOCK(filenum);
   assert(ccode()==CCE);
}
static void update_records(void)
{
   /* Update department code for several employees */
   const struct {char empno[5]; char new_dept[4];} update_data[] =
      {{"28766", "9901"}, {"11111", "9905"}};
   const int update_items =
      sizeof update_data / sizeof update_data[0];
   int i;
   record_t buffer;
   for (i=0; i<update_items; ++i)
      {
      printf("Updating employee %.5s to department %.4s:  ",
             update_data[i].empno, update_data[i].new_dept);
      lock_file();
      FREADBYKEY(filenum, buffer, - sizeof buffer,
                 update_data[i].empno, 0);
      assert(ccode()==CCE);
      printf("%.20s\n", buffer+5);
      memcpy(buffer+34, update_data[i].new_dept, 4);
      FUPDATE(filenum, buffer, - sizeof buffer);
      assert(ccode()==CCE);
      unlock_file();
      }
   printf("\n");
}
static void write_new_records(void)
{
   /* Add some entries to the file */
   const record_t test_data[] =
      {
      "77777NEWMAN GEORGE       7770066661520871012",
      "55555GOODMAN BRIAN       5553300008540880815",
      "66666MANLEY SHAUNA       0003526143360890930"
      } ;
   const int test_items = sizeof test_data / sizeof test_data[0];
   int i;
   for (i=0; i<test_items; ++i)
      {
      lock_file();
      write_record(test_data[i]);
      unlock_file();
      }
   printf("\n");
}
static void write_record(const char * const record)
{
   /* Write one record to the file */
   printf("Writing record for %.5s, %.20s\n", record, record+5);
   FWRITE(filenum, record, - sizeof(record_t), 0);
   assert(ccode()==CCE);
}
 |  
  
 |