This Appendix contains examples in C using direct Adabas calls.
This document covers the following topics:
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 ); }
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 ); } }