[comp.databases] Informix Header Routine

flak@slovax.UUCP (Dan Flak) (06/27/87)

In a prior article Prentiss Riddle gave us some awk scripts
to make structures for ALL-II routines.

> Caveats: these scripts aren't extremely smart, and in particular they
> can be confused by comments (I get around this by beginning each
> comment line between the "{" and "}" with a "#").  If someone would
> like to take this idea and turn it into an idiot-proof C program, I
> would be delighted. 

OK, I couldn't resist the challenge. The program is called "dbheader",
and it takes the database name and file name as arguments. Output
goes to standard output.

Watch out for my .signature on the end!
#-------- cut here, and unpack with 'sh' -----------------------------

#! /bin/sh
echo shar: extracting README
if test -f 'README' ; then
    echo shar: will not overwrite README
else
    cat > README << '@EOF README'

The following program converts an Informix schema into the C structures
needed for interfacing with ALL-II routines.

Output can be redirected into your favorite include file.

The following is an example of what the program can do.

The input schema looks like:

--------------------
database bar

file foo

field foo_1    type character 10  index dups
field foo_2    type integer       index dups
field foo_3    type long
field foo_4    type double
field foo_5    type float
field foo_6    type serial
field foo_7    type date
field foo_8    type edate
field foo_9    type ydate
field foo_10   type money
field foo_11   type composite foo_1, foo_2 index primary

end
--------------------

and it was "dbbuilt" to produce database bar. With DBPATH set to the
appropriate directory, I ran

    dbheader bar foo > foo.h

foo.h looks like:

--------------------
struct dbview foo_view [] =
    {
    {"foo_1"},
    {"foo_2"},
    {"foo_3"},
    {"foo_4"},
    {"foo_5"},
    {"foo_6"},
    {"foo_7"},
    {"foo_8"},
    {"foo_9"},
    {"foo_10"}
    };

int foo_view_num = 10;

struct
    {
    char   foo_1[11];
    int    foo_2;
    long   foo_3;
    double foo_4;
    float  foo_5;
    long   foo_6;
    long   foo_7;
    long   foo_8;
    long   foo_9;
    double foo_10;
    } foo_buf;
--------------------

The variable foo_view_num is the number of data elements in the view.
It comes in handy as in:

   dbstructview ("foo",foo_view,foo_view_num);

The Makefile has no provision for "install". Put the executable
where ever you please.

If you have comments, suggestions, or flames, please send them to:

{psivax,ism780}!logico!slovax!flak  :  {hplsla,uw-beaver}!tikal!slovax!flak
Dan Flak-R & D Associates,3625 Perkins Lane SW,Tacoma,Wa 98499,206-581-1322
@EOF README
if test 1764 -ne "`wc -c < README`"; then
    echo shar: checksum error - number of characters should be 1764
fi
fi
chmod 666 README
echo shar: extracting dbheader.c
if test -f 'dbheader.c' ; then
    echo shar: will not overwrite dbheader.c
else
    cat > dbheader.c << '@EOF dbheader.c'

/*+
 * File: dbheader.c
 * Description:
 *    Make Informix dbview and buffer
 *
 * This module is the property of Cottege Computing
 * donated to the public domain
 *
 * Audit Trail:
 *    06/26/87 - Original program by Dan Flak
 *
-*/

#ifdef VERSION
static char *SCCS = "%Z% %M%:%I% %G% %U%";
#endif

/* #includes */
#include <stdio.h>
#include <dbio.h>

/* #defines */
#define MAXFIELDS 100

/* external variables */

/* referenced external functions */

/* internal functions */

/* global variables */

struct fields
	{
	char name[100];
	int  type;
	int  size;
	} array[MAXFIELDS];                 /* array of field attributes       */

                                        /* data types                      */
char *dbtype [] = {"char","int","long","double","float"};

/* static variables */


/*<
 * Function: main (argc, argv)
 * Description:
 *    Produce a dbview and structure for an indicated Informix File
 *
 * Arguments:
 *    argv[1] - Informix Database Name
 *    argv[2] - Informix File Name
 *
 * Returns:
 *    Output streamed to stdout.
 *
 * Side Effects:
 *
 * Calls:
 *
 * PDL:
 *   Use the dbfile and dbnfield calls in the Informix ALL Library
 *   to get field information.
 *
>*/

main (argc, argv)
int  argc;
char *argv[];
{
short i;                                /* counter                         */
int   cc;                               /* Informix function return        */
short numflds;                          /* Number of fields in file        */
short recsize;                          /* Record size                     */
short perms;                            /* File permissions                */
char  filename[15];                     /* File name                       */
char  fldname[100];                     /* Field name                      */
short type;                             /* Type of field                   */
short len;                              /* Field length                    */
int   viewnum = 0;                      /* Number of fields in view        */

strcpy (filename,argv[2]);

cc = dbselect (DBOPEN,argv[1]);
if (cc)
	{
	exiterror (cc,"Can't open database",argv[1]);
	}

                                        /* get file information            */
cc = dbfile (filename, &numflds, &recsize, &perms);
if (cc)
	{
	exiterror (cc,"Problem finding information for file",filename);
	}

for (i = 0; i < numflds; i++)
	{
	cc = dbnfield (i, filename, fldname, &type, &len, &perms);
	if (cc)
		{
		exiterror (cc,"Problem finding information for field",fldname);
		}
	if (type != COMPOSTYPE)
		{
		strcpy (array[viewnum].name,fldname);
		switch (type)
			{
			case CHARTYPE:
				array[viewnum].type = 0;
				array[viewnum].size = len + 1;
			break;
			case INTTYPE:
				array[viewnum].type = 1;
			break;
			case LONGTYPE:
				array[viewnum].type = 2;
			break;
			case DOUBLETYPE:
				array[viewnum].type = 3;
			break;
			case FLOATTYPE:
				array[viewnum].type = 4;
			break;
			case SERIALTYPE:
				array[viewnum].type = 2;
			break;
			case DATETYPE:
				array[viewnum].type = 2;
			break;
			case EDATETYPE:
				array[viewnum].type = 2;
			break;
			case YDATETYPE:
				array[viewnum].type = 2;
			break;
			case MONEYTYPE:
				array[viewnum].type = 3;
			break;
			default:
				exiterror (-1,"Can't find type for field",fldname);
			break;
			}
		viewnum++;
		}
	}

cc = dbselect (DBCLOSE,argv[1]);
if (cc)
	{
	exiterror (cc,"Can't close database",argv[1]);
	}

viewnum--;                              /* there's an extra one left over  *
                                         * after the last successful find  */

/*  print dbview array                                                     */

printf ("struct dbview %s_view [] =\n",filename);
printf ("    {\n");

for (i = 0; i < viewnum; i++)
	{
	printf ("    {\"%s\"},\n",array[i].name);
	}

printf ("    {\"%s\"}\n",array[viewnum].name);

printf ("    };\n\n");

/*  print dbview number                                                    */

printf ("int %s_view_num = %d;\n\n",filename,viewnum + 1);

/* print buffer structure                                                  */

printf ("struct\n");
printf ("    {\n");

for (i = 0; i <= viewnum; i++)
	{
	if (array[i].type)
		{
		printf ("    %-6s %s;\n", dbtype[array[i].type], array[i].name);
		}
	else
		{
		printf ("    %-6s %s[%d];\n",
			dbtype[array[i].type], array[i].name, array[i].size);
		}
	}

printf ("    } %s_buf;\n",filename);

exit (0);
}


/*<
 * Function: exiterror (errno, errmsg1, errmsg2)
 * Description:
 *    Exit the program with an error message
 *
 * Arguments:
 *    errno   - error message code
 *    errmsg1 - error message
 *    errmsg2 - additional information
 *
 * Returns:
 *
 * Side Effects:
 *
 * Calls:
 *
 * PDL:
 *
>*/

int exiterror (errno, errmsg1, errmsg2)
int  errno;
char *errmsg1, *errmsg2;
{
fprintf (stderr, "%d - %s %s\n", errno, errmsg1, errmsg2);
exit (errno);
}
@EOF dbheader.c
if test 4914 -ne "`wc -c < dbheader.c`"; then
    echo shar: checksum error - number of characters should be 4914
fi
fi
chmod 666 dbheader.c
echo shar: extracting Makefile
if test -f 'Makefile' ; then
    echo shar: will not overwrite Makefile
else
    cat > Makefile << '@EOF Makefile'
all:		dbheader 
			touch all

clean:
			rm -f dbheader 

dbheader:	dbheader.c
			cc -o dbheader dbheader.c -ldb

@EOF Makefile
if test 113 -ne "`wc -c < Makefile`"; then
    echo shar: checksum error - number of characters should be 113
fi
fi
chmod 666 Makefile
-- 
{psivax,ism780}!logico!slovax!flak  :  {hplsla,uw-beaver}!tikal!slovax!flak
Dan Flak-R & D Associates,3625 Perkins Lane SW,Tacoma,Wa 98499,206-581-1322