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