Appendix C - C Examples

#### Search Results

Search

# Appendix C - C Examples

This Appendix contains examples in C using direct Adabas calls.

This document covers the following topics:

- C Example

- C Example for LOB Processing

## C Example

The Adabas file defined in Appendix B is used in this example.

    /************* ADABAS  ************* (C) Copyright Software AG 2005
    *
    * File       : c_example.c
    * Description: Example for ADABAS calls from C programs
    *
    *
    *************************************************************************/

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    #include <adabasx.h>                /* include adabas definitions */

    #define NULLPTR ((char *) 0)       /* define for NULL-pointer */

    int dbid;                          /* default database */
    int emp_file ;                     /* filenumber       */

    #define FMTBUF  "LB1,4,F."         /* FB: get first salary field */
    #define FBLEN   8                  /* format buffer's length    */

    #define SEABUF  "BC,5."            /* SB: search NAME equal to  */
    #define SBLEN   5                  /* search buffer's length    */

    #define VALBUF  "SMITH"            /* VB: name to search for    */
    #define VBLEN   5                  /* value buffer's length     */

    #define RBLEN   4                  /* record buffer's length    */
    #define IBLEN   4                  /* ISN buffer's length       */

    char openrb[100];                    /* record buffer used for OPEN */

    /*
            +----------------+
            ! define buffers !
            +----------------+
    */

    static CB_PAR  cb;         /* control block */

    static int     isn_buffer;     /* ISN buffer (1 ISN) */

    static int     rb_salary;          /* record buffer (for salary field) */

    /*************************************************************************/
    /**                 Module Local Functions                              **/
    /*************************************************************************/

    int      usage ();
    int      open_database ();
    int      close_database();
    void     response ();
    int      update_record();
    int      find_record();
    int      issue_bt ();

    usage()
    {
        printf("usage: c_example <dbid> <employees file number>\n");
        exit(1);
    }

    /*
            +------------------+
            !   Main program   !
            +------------------+
    */

    int main (int argc, char **argv )
    {
       register int   upd = 0;          /* update counter */
       register int   old_salary;           /* saving salary field */

       printf ("\nSoftware AG - C example program for calling ADABAS\n\n") ;

       if (argc==3)
       {
           if (sscanf (argv[1],"%d",&dbid)==0)
           usage ();
           if (sscanf (argv[2],"%d",&emp_file)==0)
           usage ();
       }
       else
           usage();

       /*--------------*/
       /* Open session */
       /*--------------*/
       if ( open_database() != ADA_NORMAL )
          response ();              /* open command failed */
       else
       {
          /*--------------------------------------*/
          /* Search all persons with name = SMITH */
          /*--------------------------------------*/
          if ( find_record () == ADA_NORMAL )
          {
             printf ("Found  %ld records with name %s, increase salary by 10 %%\n",
             cb.cb_isn_quantity, VALBUF);

             while ( cb.cb_return_code == ADA_NORMAL  &&  cb.cb_isn_quantity != 0 )
             {
                old_salary = rb_salary;
                rb_salary += rb_salary / 10;

            /*-------------------------*/
            /* Increase salary by 10 % */
            /*-------------------------*/
                if ( update_record () != ADA_NORMAL )
                   cb.cb_isn_quantity = 0;
                else
                {
                   upd++;
                   printf
                      ("%3d. ISN = %8d  old salary = %10ld   new salary = %10ld\n",
                        upd, cb.cb_isn, old_salary, rb_salary);

               /*-----------------*/
               /* Get next record */
               /*-----------------*/
                   find_record ();
                }
             }
          }

          if ( cb.cb_return_code != ADA_NORMAL )    /* if response given: */
          {
             response ();               /* display response code */
             cb.cb_return_code = ADA_NORMAL;

             if ( upd != 0 )            /* if updates done */
         {
                if ( issue_bt () == ADA_NORMAL )    /* backout transaction */
                   upd = 0;
                else
                   response ();         /* BT failed */
         }
          }

          if ( close_database () != ADA_NORMAL )
             response ();
       }
    }

    /*
            +------------------------+
            ! Open the database for  !
            ! updating the EMPLOYEES !
            ! file                   !
            +------------------------+
    */

    int open_database ()
    {

       cb.cb_cmd_code[0] = 'O';
       cb.cb_cmd_code[1] = 'P';

       sprintf(openrb,"UPD=%d.",emp_file);

       cb.cb_rec_buf_lng = strlen(openrb);
       do
       {
          CB_SET_FD(&cb,dbid,0);
          adabas ( &cb , NULLPTR , openrb, NULLPTR, NULLPTR, NULLPTR );
       }
       while ( cb.cb_return_code == ADA_TABT );

       cb.cb_isn_quantity = 0;
       cb.cb_isn_ll = 0;

       return ( cb.cb_return_code );
    }

    /*
            +--------------------------------+
            !  Close the database and give   !
            !  implicit end of transaction.  !
            +--------------------------------+
    */

    int close_database ()
    {
       CB_SET_FD(&cb,dbid,0);

       cb.cb_cmd_code[0] = 'C';
       cb.cb_cmd_code[1] = 'L';

       adabas ( &cb, NULLPTR, NULLPTR, NULLPTR, NULLPTR, NULLPTR );

       return ( cb.cb_return_code );
    }

    /*
            +--------------------------------+
            ! Call ADABAS to find all people !
            ! named SMITH and read them      !
            +--------------------------------+
    */

    int find_record ()
    {

       CB_SET_FD(&cb,dbid,emp_file);

       if ( cb.cb_isn_quantity == 0 )       /* if first call:       */
       {                        /*   search records and */
          cb.cb_cmd_code[0]  = 'S';         /*   read first one     */
          cb.cb_cmd_code[1]  = '4';
          cb.cb_cmd_id[0]    = 'F';
          cb.cb_cmd_id[1]    = 'I';
          cb.cb_cmd_id[2]    = 'N';
          cb.cb_cmd_id[3]    = 'D';

          cb.cb_fmt_buf_lng  = FBLEN;
          cb.cb_rec_buf_lng  = RBLEN;
          cb.cb_sea_buf_lng  = SBLEN;
          cb.cb_val_buf_lng  = VBLEN;
          cb.cb_isn_buf_lng  = IBLEN;       /* read 1. record by search */
       }
       else                     /* if subsequent call: */
       {                        /*   read next record  */
          cb.cb_cmd_code[0] = 'L';
          cb.cb_cmd_code[1] = '4';
          cb.cb_cop2         = ADA_GET_NEXT;    /* activate get-next option */
       }

       adabas ( &cb , FMTBUF , &rb_salary , SEABUF , VALBUF , &isn_buffer );

       if ( cb.cb_return_code == ADA_EOF )
       {
          cb.cb_return_code   = ADA_NORMAL;     /* indicate success */
          cb.cb_isn_quantity  = 0;          /* force termination of loop */
       }
       return ( cb.cb_return_code );
    }

    /*
            +----------------------------+
            ! Change the value of salary !
            !  and update the record     !
            +----------------------------+
    */

    int update_record ()
    {
       CB_SET_FD(&cb,dbid,emp_file);

       cb.cb_cmd_code[0] = 'A';
       cb.cb_cmd_code[1] = '1';
       cb.cb_cop1 = cb.cb_cop2 = ' ';

       adabas ( &cb , FMTBUF , &rb_salary, NULLPTR, NULLPTR, NULLPTR );

       return ( cb.cb_return_code );
    }

    /*
            +-----------------------+
            !  printf response code  !
            +-----------------------+
    */

    void response ()
    {
       printf ("** Response code %d from ADABAS for Command %-2.2s\n",
                cb.cb_return_code , cb.cb_cmd_code);
       printf ("** Additions2 %d %d\n",
                cb.cb_add2[2] , cb.cb_add2[3]);

    }

    /*
            +--------------------+
            !  Issue BT command  !
            +--------------------+
    */

    int issue_bt ()
    {
       CB_SET_FD(&cb,dbid,0);

       cb.cb_cmd_code[0] = 'B';
       cb.cb_cmd_code[1] = 'T';
       cb.cb_cop1 = cb.cb_cop2 = ' ';

       adabas ( &cb, NULLPTR, NULLPTR, NULLPTR, NULLPTR, NULLPTR );

       return ( cb.cb_return_code );
    }

## C Example for LOB Processing

This example works with any file that contains an elementary LOB field; the database ID, file number and name of the LOB field can be passed to the program as parameters.

    /************* ADABAS  ************* (C) Copyright Software AG 2006 **********
    *
    * File       : lob_example.c
    *
    * Description: Example for ADABAS calls from C programs
    *
    *          This is an example how read and write large objects in a database
    *          or to read an object from a database
    *
    *          Parameters:
    *           function (add_lob or read_lob)
    *           Database-ID
    *           Filenr
    *           Isn
    *           fieldname
    *           filename
    *
    *           The add_lob function reads a disk file and adds or updates the
    *           content of a specified field in a database. This is done by an
    *           ADABAS A1 call.
    *           The record must exist and the given field is updated.
    *
    *           The read_lob function does two L1 calls to retrieve the size and
    *           the content of a given field in a database. The content is then
    *           written to a disk file.
    *
    *
    *           adabasx()is required for buffers greater than 64 K.
    *           The buffers are described by ABD structures (ADABAS Buffer
    *           descritpions) that are passed as arguments to adabasx.
    *           More than one pair of ABDs for record and format buffer can be used.
    *           (See function add_lob)
    *           This means that not all data has to be in one continuous memory
    *           area.The ABDs are initialized by the SETABD macros.
    *
    *
    *****************************************************************************/

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/stat.h>
    #include "adabasx.h"        /* include adabas definitions */

    /* opening the database */
    void open_database( int dbid );

    /*close the database */
    void close_database( int dbid );

    /*usage descriptions */
    void usage( );

    /* display response code */
    void response( ACBX *cbx );

    /* read from database */
    void read_lob( int dbid, int filenr, int isn, char *filename, char *field );

    /* write in the database */
    void add_lob( int dbid, int filenr, int isn, char *filename, char *field );

    /* read from the file */
    int  read_file( char *filename, void **obj);

    /* write LOB to file */
    void write_file( char *filename, char *obj, unsigned int objsize  );

    int main ( int argc, char **argv )
    /*
        Main function
        read the argument and pass control to one of the functions
    */

    {
        int filenr, dbid, isn;    /* variables for adabas call        */
        char * command = NULL;      /* command to execute (read/write)*/
        char * filename = NULL;     /* filename                       */
        char *field;          /* field of the database                */

        printf("\nSoftware AG - C example program for calling ADABAS with large");
        printf(" objects\n\n    add/read a large object to/from a record \n\n");

        if( argc != 7 )
            usage( );
        else
        {
            command = &argv[1][0];

            if( ( strcmp( command ,"add_lob") != 0 )
                  && ( strcmp( command, "read_lob") != 0 ) )
            {
                usage ( );
            }

            if( sscanf( argv[2],"%d",&dbid ) == 0 )
                usage( );

            if( sscanf (argv[3],"%d",&filenr ) == 0 )
                usage( );

            if( sscanf (argv[4],"%d",&isn ) == 0 )
                usage( );

            field = argv[5];

            filename = argv[6];
        }

        open_database( dbid );      /* Open database            */

                        /* read in the database         */
        if( strcmp( command, "add_lob" ) == 0 )
            add_lob( dbid, filenr, isn, filename, field );
        else                /* Write from database          */
            read_lob( dbid, filenr, isn, filename, field );

        close_database( dbid );     /* Close database           */

    }

    void usage( )
    /*----------------------------------------
        Display how the program has to be used
    ------------------------------------------*/
    {
    printf("usage:\n");
    printf("    lob_example (add_lob | read_lob) <dbid> <file> <isn> <field> <file name>");
    printf("\n\n");
    printf("    add_lob  : Read an object from <file name> and update <field> in record\n");
    printf("    read_lob : Read from database, save to file on disk\n");
    printf("    dbid     : Number of ADABAS database\n");
    printf("    file     : Number of file\n");
    printf("    isn      : ISN of record to be updated/read\n");
    printf("    field    : Field where object is (to be) stored\n");
    printf("    file name: Name of the disk file to be read or written\n\n");
    printf("    ie.: lob_example add_lob 12 9 1100 RA picture.jpg \n");
    printf("    ie.: lob_example read_lob 12 9 1100 RA picture.jpg\n");
        exit(1);
    }

    void open_database( int dbid )

    /*-------------------------------------------------
      Open the database

      This call is done with conventional adabas
      function.
      All other calls are done via adabasx to show that
      The two types of calls can be mixed.
    -------------------------------------------------*/

    {

        CB_PAR cb;                          /* Control block        */
        char *open_rb = ".";

        memset(&cb,0,sizeof(cb));

        cb.cb_call_type=0;

        cb.cb_cmd_code[0] = 'O';            /* open options         */
        cb.cb_cmd_code[1] = 'P';
        CB_SET_FD(&cb,dbid,0);
        adabas( &cb, 0, open_rb , 0 ,0 ,0); /* adabas call          */

        if( cb.cb_return_code != 0 )
        {
            printf("Open of Database %d failed with response %d\n",
            dbid,
            cb.cb_return_code );
            exit(1);
        }
    }

    void read_lob( int dbid, int filenr, int isn, char *filename, char *field )
    /*--------------------------------------------+
      Read a large object from database
      two L1 calls are done:
      the first to determine the size of the object.
      then a buffer with this size is allocated.
      the second reads the actual object.
    +---------------------------------------------*/
    {
    #define abdcount 4
        char i=0;
        ACBX cbx;                   /* Control block                    */
        ABD  object_fb_abd;         /* Format buffer ABD for the object */
        ABD  object_rb_abd;         /* Record buffer ABD for the object */
        ABD  object_size_fb_abd;    /* Format buffer ABD for the size   */
        ABD  object_size_rb_abd;    /* Record buffer ABD for the size   */

        ABD* pabd[abdcount];        /* ABD array for Adabas call        */

        char size_fb[20];           /* format buffer for size           */
        char object_fb[30];         /*format buffer to retrieve the     */
                                    /*object itself                     */
        unsigned int object_size;   /*The 4-Byte integer object_size    */
                                    /*is our record buffer              */
                                    /*for the first call                */
        unsigned int object_size_chk;/*store the size to check if object*/
                                    /*changed between the calls         */

        SETACBX ( &cbx );

        cbx.acbxdbid   = dbid;
        cbx.acbxfnr    = filenr;
        cbx.acbxisn    = isn;
        cbx.acbxcmd[0] = 'L';       /* Command code         */
        cbx.acbxcmd[1] = '1';

        /*Initialize the abds*/
        pabd[0] = &object_size_fb_abd;
        pabd[1] = &object_size_rb_abd;
        pabd[2] = &object_fb_abd;
        pabd[3] = &object_rb_abd;

        /*Initialize abd*/
        for (i=0 ;i< abdcount;i++)
        {
            SETABD  ( pabd[i] );
            pabd[i]->abdloc = ABDQIND;
        /*  ABDQIND means that the buffer is found at abdaddr   */
        }

        object_size_fb_abd.abdid    = ABDQFB;
        sprintf( size_fb, "%sL.", field );
        object_size_fb_abd.abdaddr  = size_fb;
        object_size_fb_abd.abdsend  =
        object_size_fb_abd.abdsize  = strlen( size_fb );

        object_size_rb_abd.abdid    = ABDQRB;
        object_size_rb_abd.abdaddr  = &object_size;
        object_size_rb_abd.abdsize  = sizeof(object_size);

        adabasx ( &cbx, 2 , pabd );
        response( &cbx );

        printf("Size of Object in Database :%d     \n\n",object_size);
        if (object_size)
        {
            object_fb_abd.abdid    = ABDQFB;

            sprintf( object_fb, "%s,*.", field );
            object_fb_abd.abdaddr  = object_fb;
            object_fb_abd.abdsend = object_fb_abd.abdsize  = strlen(object_fb);

            object_rb_abd.abdid    = ABDQRB;

            do {
                object_size_chk=object_size;

                /*Now the memory for the object is allocated                */
                /*and the object itself is read by a second call            */
                /*the lenth is read again to verify that it is unchanged    */
                object_rb_abd.abdsize  = object_size_chk;
                if (object_rb_abd.abdaddr)
                    free(object_rb_abd.abdaddr);
                object_rb_abd.abdaddr  = malloc ( object_size_chk);
                if (object_rb_abd.abdaddr)
                {
                    adabasx ( &cbx , 4 , pabd );    /* Adabas call  */
                    response( &cbx );

                }
                else
                {
                    printf ("*** Memory allocation for Record Buffer failed");
                    close_database(dbid);
                    exit (-1);
                }
             } while (object_size>object_size_chk&&object_size);
        }
        if (object_size)
        {
    write_file( filename, object_rb_abd.abdaddr, (unsigned int)object_rb_abd.abdsize );
    printf("Object from field %s ISN %d file %d Database %d successfully written\nto file %s\n\n",
    field,isn,filenr,dbid,filename);
        }
        else
        {
    printf("No Object found in field %s ISN %d file %d Database %d\n",
    field,isn,filenr,dbid);
    printf("No file written\n\n");
        }

    }

    void write_file( char *filename, char *obj, unsigned int objsize  )
    /*--------------------------------------------
        write LOB to disc file
    ---------------------------------------------*/
    {
        FILE * fd;
        struct stat st;        /* to specify the exists of the file */

        if(stat(filename , &st) > 0)
        {
            printf("The file %s already exists!\n\n", filename);
            exit( 1 );
        }
                        /* open the file            */
        if( ( fd = fopen( filename, "wb+" ) ) == NULL )
        {
            printf("File %s could not be opened for writing!\n\n", filename);
            exit( 1 );
        }
                        /* write in the file        */
        else if ( fwrite ( obj, 1, objsize, fd ) < 0 )
        {
            printf("Cannot write to file %s\n\n", filename);
            exit( 1 );
        }
        fclose(fd);
    }

    void add_lob( int dbid, int filenr, int isn, char *filename, char *field)
    /*----------------------------------------------------------
        add a large object to a record in a  database.
        for demonstration purposes two pairs of record and format
        buffer segments are used:
        one pair is used to specify the size of the object
        one pair is used for the object itself
     ----------------------------------------------------------*/
    {
    #define abdcount 4
        char i=0;
        ACBX cbx;                   /* Control block                    */
        ABD  object_fb_abd;         /* Format buffer ABD for the object */
        ABD  object_rb_abd;         /* Record buffer ABD for the object */
        ABD  object_size_fb_abd;    /* Format buffer ABD for the size   */
        ABD  object_size_rb_abd;    /* Record buffer ABD for the size   */

        ABD* pabd[abdcount];        /* ABD array for Adabas call        */

        char size_fb[20];           /* format buffer for size           */
        char object_fb[20];         /* format buffer for content        */
        int object_size;

        SETACBX ( &cbx );           /* Initialing abds                  */
        cbx.acbxdbid = dbid;
        cbx.acbxfnr  = filenr;
        cbx.acbxisn  = isn;
        cbx.acbxcmd[0] = 'A';       /* Record Update                    */
        cbx.acbxcmd[1] = '1';
        cbx.acbxcop1   = 'H';       /* Hold status database             */

        pabd[0] = &object_size_fb_abd;
        pabd[1] = &object_fb_abd;
        pabd[2] = &object_size_rb_abd;
        pabd[3] = &object_rb_abd;

        /*Initialize abd*/
        for (i=0 ;i< abdcount;i++)
        {
            SETABD  ( pabd[i] );
            pabd[i]->abdloc = ABDQIND;
        /*  ABDQIND means that the buffer is found at abdaddr           */
        }

        /*the object is stored in a pair of rb and fb                   */
        object_fb_abd.abdid     = ABDQFB;
        object_fb_abd.abdaddr   = object_fb;
        sprintf (object_fb,"%s,*.",field);
        object_fb_abd.abdsend = object_fb_abd.abdsize = strlen(object_fb);
        strlen(object_fb);

        object_rb_abd.abdid    = ABDQRB;
        /*store the size of the object in the abdsize field             */
        /*this field is also used as the second record buffer segment*/

        object_size = (int)read_file( filename, &object_rb_abd.abdaddr);
        object_rb_abd.abdsend = object_rb_abd.abdsize = object_size ;

        printf("** Size of Object to add:%d     \n\n",object_rb_abd.abdsize);

        /*the size of the object is stored in a separate pair           */

        object_size_fb_abd.abdid  = ABDQFB;
        object_size_fb_abd.abdaddr=size_fb;
        sprintf (size_fb,"%sL.",field);
        object_size_fb_abd.abdsend = object_size_fb_abd.abdsize
            = strlen(size_fb);

        object_size_rb_abd.abdid = ABDQRB;
        object_size_rb_abd.abdsend = object_size_rb_abd.abdsize
            = sizeof(object_size);

        object_size_rb_abd.abdaddr=&object_size;

        adabasx ( &cbx , abdcount,  pabd );    /* Adabas call           */

        response( &cbx );

    printf("Object successfully added/updated in field %s ISN %d file %d Database %d\n\n",
     field,isn,filenr,dbid);

    #undef abdcount
    }

    int  read_file( char *filename, void **obj)
    /*------------------------------------
     allocate memory for the record buffer and
     read a file into it
    +--------------------------------------*/
    {
        unsigned int filelength;
        FILE * fd;
        struct stat st;

        /*  determine the length of  file    */

        if( stat(filename , &st) < 0 )
        {
            printf("The file %s doesn't exist!\n\n", filename);
            exit (1);
        }

        if( ( filelength = st.st_size ) < 0 )
        {
            printf("File % could not be opened!\n\n", filename);
            exit( 1 );
        }

                        /* open the file            */
        if( !filename || ( fd = fopen( filename, "rb" ) ) == NULL )
        {
            printf("File % could not be opened!\n\n", filename);
            exit( 1 );
        }

        if (!(*obj=malloc (filelength)))
        {
            printf("Could not allocate memory\n\n");
            exit( 1 );
        }

        filelength=fread( *obj, sizeof(char), filelength / sizeof(char), fd );

        fclose ( fd );

        if( filelength < 0 )
        {
            printf("Could not read  from the file: %s\n\n", filename);
            exit( 1 );
        }

        return  filelength;
    }

    void close_database( int dbid )
    /*----------------------------+
      Close the session and give
      implicit end of transaction.
    +----------------------------*/

    {
        ACBX cbx;               /* Control block            */

        SETACBX( &cbx );        /* Initialize the Control      Block*/
        cbx.acbxcmd[0] = 'C';       /* put close option         */
        cbx.acbxcmd[1] = 'L';
        cbx.acbxdbid = dbid;

        adabasx( &cbx , 0 , NULL);      /* adabas call              */

        response( &cbx );

        if( cbx.acbxrsp != 0 )
             printf("** Close failed with response %d\n\n", cbx.acbxrsp);
    }

    void response( ACBX *cbx )
    /*-----------------+
    print response code
    +------------------*/

    {
        if( cbx->acbxrsp != 0)
        {
            printf("** Response code from ADABAS for Command %-2.2s:     %d\n\n",
            cbx->acbxcmd, cbx->acbxrsp);
            if( cbx->acbxrsp == ADA_LOBERR)
            {
                printf("** subcommand response %d\n\n",cbx->acbxerrc);
            }
            if ( cbx->acbxrsp != ADA_ANACT)
            {
                    close_database(cbx->acbxdbid);
            }
            exit( 1 );
        }

    }

### On this page

- C Example
- C Example for LOB Processing