HPlogo Using KSAM XL and KSAM 64 > Appendix C HP C/iX Example Program

Appendix C HP C/iX Example Program

MPE documents

Complete PDF
Table of Contents
Index

E0300 Edition 4 ♥
E0394 Edition 3

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

Example HP C/iX Program:

  #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);
  }




BKWRITE


Index