[comp.databases] ORACLE SQLFORMS REPORT TOOL

raym@hechcx.HEC.HARRIS.COM (Ray Morin) (04/07/89)

  Hello,
          I was in an Oracle class recently and was told there is a RPT
program (public domain) that was written at oracle that will generate
documentation on SQL*FORMS applications. I have one called form.rpt and 
form23.rpt ( same as form but modified for SQLFORMS version 2.3 ) that 
generates a report on more or less only field level triggers and field
characteristics but doesn't report on block level ( step by step ) triggers.
* ( i got this from the class )
                    There is supposed to be a RPT program called block.rpt
that will document block/?and?/form level triggers. If anyone has this
I would greatly appreiciate if they would mail me a copy of it or 
any other useful tool of this type.

                                           Thanks,
                                             raym@hechcx
 
         

midkiff@Thalatta.COM (Michelle Midkiff) (04/11/89)

Sorry for posting this, but email bounced.

In article <868@hechcx.HEC.HARRIS.COM> raym@hechcx.HEC.HARRIS.COM (Ray Morin) writes:
				<< some text deleted for brevity>>
>program (public domain) that was written at oracle that will generate
>documentation on SQL*FORMS applications. I have one called form.rpt and 
>form23.rpt ( same as form but modified for SQLFORMS version 2.3 ) that 
>generates a report on more or less only field level triggers and field
>characteristics but doesn't report on block level ( step by step ) triggers.
>* ( i got this from the class )
>                    There is supposed to be a RPT program called block.rpt
>that will document block/?and?/form level triggers. If anyone has this


Ray,
  I haven't heard of a block.rpt program, but the form.rpt that I have
generates a report that includes form, block, and field level triggers
and characteristics.  The last modification date on it is 6/22/87.  If
you don't receive it from anyone else, let me know and I'll send you a
copy.  If this isn't what you had in mind, have you tried your local 
Oracle sales rep?  That's what Oracle directed us to do when we were 
trying to get a copy of form.rpt.  They said he could get it for us.

								  - Michelle
-- 

In-Real-Life: Michelle Midkiff, Thalatta Corporation, (+1 206 455 9838)
Domain: midkiff@Thalatta.COM    Path: ...!sun!sunup!thebes!midkiff

tony@ajfcal.UUCP (Tony Field) (04/21/89)

>     IN ARTICLE <868@hechcx.HEC.HARRIS.COM>, 
> 		raym@hechcx.HEC.HARRIS.COM (Ray Morin) WRITES:
> >                       There is supposed to be a RPT program called block.rpt
> >   that will document block/?and?/form level triggers. If anyone has this
> >   I would greatly appreciate if they would mail me a copy of it or 
> >   any other useful tool of this type.
> 
>     You may well find the following Bourne shell script rather more useful
>     than any of the RPT programs floating around. I'm posting, rather than
>     mailing, as I think that it will be of general interest to those using
>     Oracle with UNIX or similar systems; ...

This routine looks very useful, however it does not run under Xenix 2.2.3.
Awk gets all confused:

        1st pass on myform
        2nd pass on myform
        awk: regular expression too long    <======

(((-> Some people keep trying to tell me that Xenix is really Unix.... <-)))

Since I don't understand the awk word religion, I cannot correct this problem.
(humm.  maybe someone will email me gnuawk...).

For Xenix users, I offer the following two pieces of c code that does similar
things to Jim G's script, however will work under Xenix 2.2.3 against .inp 
files generated by Oracle version 5.1.17 edition of SqlForms.

It does not print out everything:  I chose only to print trigger and
and commentary information - to keep the confusion level down.

There is no Makefile:  i simply say "make pform" and "make index" - which
works under Xenix 2.2.3.  (((I also use source code tab stops set to 4.)))

On a slightly different subject, I have a c programme which will allow
xenix users to automatically convert .inp files for  msdos or for any
terminal described in the termcap data base.  It is rather lengthy,
but if enough interest is shown, I could post it to comp.sources.unix or
to comp.sources.misc.  It also runs for Oracle 5.1.17 - I haven't yet
converted to the new release......

((ps i hope no one really flames us for post source to what is supposed
     to be a discussion group for data base theory and management issues.
     
     Maybe someone from Oracle Corp. will volunteer to set up a news
     group for comp.databases.oracle.  In some ways, the network is
     a better method of addressing oracle problems than the excellent
     oracle hot-line services.))

                                         tony.
   ----------------- cut here ----------------------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  pform.c index.c
# Wrapped by ajf@ajfcal on Thu Apr 20 12:29:51 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'pform.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'pform.c'\"
else
echo shar: Extracting \"'pform.c'\" \(9367 characters\)
sed "s/^X//" >'pform.c' <<'END_OF_FILE'
X/* ta=4 */
X/************************************************************************
X*					p f o r m . c										*
X************************************************************************/
X/*
X	Scan .inp files.  print all triggers in a reasonable format.
X
X	usage:  pform f1.inp f2.inp ...
X	
XAuthor:   Tony Field      ..uunet!utai!calgary!ajfcal!tony
X
X*/
X
X#include <stdio.h>
X
XFILE	*fp;
Xchar	*getline();
Xchar	hdr[100], saveline[500];
Xint		pushed;
X
Xmain (argc, argv)
Xint	argc;
Xchar	*argv[];
X{
X	int		i, j;
X	char	line[500];
X	char	fieldname[200];
X	char	blockname[200];
X	char	trigger[200];
X	char	last;
X	
X
X	for (i = 1;  i < argc;  i++)
X	{
X		pushed = 0;
X		*saveline = '\0';
X		*line = 0;
X		*fieldname = 0;
X		*blockname = 0;
X		*trigger = 0;
X		strcpy (blockname, "preform");
X		printf ("\n============================  %s  ============================\n", argv[i]);
X		fp = fopen (argv[i], "r");
X
X		/*	get initial comments (preform) */
X		
X		while (getline (line) != NULL)
X		{
X			if (strncmp (line, ";Application Title :", 20) == 0)
X				break;
X			if (strncmp (line + 10, "--------", 5) == 0)
X				break;
X		}
X		while (getline (line) != NULL)					/* initial comments */
X		{
X			if (strncmp (line, ";Application Title :", 20) == 0)
X				break;
X			printf ("%s\n", line);				
X		}
X
X		/*	Scan for the block and field key words */
X
X		while (getline (line) != NULL)
X		{
X			if (strcmp (line, ";Block name / Description :") == 0)
X			{
X				getline (line);
X				if (strncmp (line, "**", 2) == 0)		/* trigger definition */
X				{	strcpy (trigger, line);
X					showtrigger (blockname, trigger);
X					getsql (line);
X				}
X				else if (*line == '*')					/* block name with order by clause */
X				{
X					strcpy (blockname, line + 1);
X					trimat (blockname, '/');			/* eliminate the description */
X					showblock (blockname);
X					skip (line, 1);						/* skip the ;...: line */
X					printf ("\n");
X					fetch_and_display (line);
X				}
X				else									/* block name		*/
X				{	
X					strcpy (blockname, line);
X					trimat (blockname, '/');			/* eliminate description	*/
X					showblock (blockname);
X				}
X			}
X
X			else if (strcmp (line, ";Field name :") == 0)
X			{
X				getline (line);
X				if (*line == '*')					/* is block level trigger?*/
X				{
X					strcpy (trigger, line);
X					showtrigger (blockname, trigger);
X					getsql (line);
X				}
X				else
X				{
X					strcpy (fieldname, line);
X					if (*fieldname)
X					{	printf ("Field: %s\n", fieldname);
X						gathersql (blockname, fieldname, line);
X					}
X				}
X			}
X		}
X		fclose (fp);
X	}				
X}
X
X/****************************************************************************
X*	trim (s)																*
X*	Trim trailing blanks and \r\n from a line								*
X****************************************************************************/
X
Xtrim (s)
Xchar	*s;
X{	char	last;
X
X	last = '\0';
X	while (*s)
X	{	if (*s < ' ')
X		{	*s = '\0';
X			return ((int) last);
X		}
X		else 
X		{	last = *s++;
X		}
X	}
X	return ((int) last);
X}
X
X
X/****************************************************************************
X*	trimat (name, c)														*
X*	Truncate a line.  Replace the found character 'c' with a null.			*
X****************************************************************************/
X
Xtrimat (name,c)
Xchar	*name, c;
X{
X	while (*name)
X	{	if (*name == c)
X		{	*name = '\0';
X			break;
X		}
X		name++;
X	}
X}
X
X/****************************************************************************
X*	skip (line, n)															*
X*	Skip n lines.  If the first character of a line is a $ then print the	*
X*	line. (it is a label in the triggers).									*
X****************************************************************************/
X
Xskip (line, n)
Xchar	*line;
Xint	n;
X{	while (n--)
X	{	getline (line);
X		if (*line == '$')
X			printf ("    %s\n", line);
X	}
X}
X
X/****************************************************************************
X*	fetch_and_display (line)												*
X*	Display all lines up to the first line that is fully blank or has		*
X*	a / as the first character.  This is used to display an SQL trigger.	*
X****************************************************************************/
X
Xfetch_and_display (line)
Xchar	*line;
X{
X	while (getline (line) != NULL)
X	{
X		if (*line == '/'  ||  *line == '\0')
X			break;
X		if (*line == ';')
X			printf ("%s\n", line);
X		else
X			printf ("    %s\n", line);
X	}
X	return ((int) *line);
X}
X
X
X/****************************************************************************
X*	showblock (blockname)													*
X*	Display the name of the block in a bold fashion.						*
X****************************************************************************/
X
Xshowblock (blockname)
Xchar	*blockname;
X{
X	if (*blockname == '\0')
X		return;
X	printf ("\n\n<<<<<<<<<<<<<<<< %s >>>>>>>>>>>>>>>>>\n", blockname);
X}
X
X
X/****************************************************************************
X*	showtrigger (ref, trigger)												*
X*	Display a trigger with an arrow											*
X****************************************************************************/
X
Xshowtrigger (ref, trigger)
Xchar	*ref;
Xchar	*trigger;
X{
X	printf ("\n--> %s.%s\n", ref, trigger);
X}
X
X/****************************************************************************
X*	getline (line)															*
X*	Get the next line from the disk.  If there was a  line pushed onto the	*
X*	'save stack', then get that line instead.								*
X****************************************************************************/
X
Xchar *getline (line)
Xchar	*line;
X{	char	*how;
X
X	if (pushed)
X	{
X		if (*saveline == '%')
X			return (NULL);
X		pushed = 0;
X		strcpy (line, saveline);
X		return (saveline);
X	}
X
X	how = fgets (line, 490, fp);
X
X	if (*line == '%')
X	{	strcpy (saveline, "%");
X		pushed = 1;
X		return (NULL);
X	}
X	if (how != NULL)
X		trim (line);
X	return (how);
X}
X
X
X/****************************************************************************
X*	pushline (line)															*
X*	Copy the current line onto the one line save stack.						*
X****************************************************************************/
X
Xpushline (line)
Xchar	*line;
X{
X	pushed = 1;
X	strcpy (saveline, line);
X}
X
X
X/****************************************************************************
X*	getsql (line)															*
X*	Get sql trigger text if the next line contains an ;SQL> directive		*
X*	This is used only for pre-form triggers									*
X****************************************************************************/
X
Xgetsql (line)
Xchar	*line;
X{
X	getline (line);
X	if (strcmp (line, ";SQL>") == 0)
X	{	do
X		{
X			fetch_and_display (line);
X			skip (line, 4);
X		} while (special_lines (line) == 0);
X	}
X}
X
X
X/****************************************************************************
X*	special_lines (line)													*
X*	Get the next line.  If it is a 'special sql text line', then return		*
X*	the value '1'.   If it not one of these special lines, return '0'		*
X*	Always push the line just read onto the save stack.						*
X****************************************************************************/
X
Xspecial_lines (line)
Xchar	*line;
X{
X	getline (line);
X	if (strcmp (line, ";Block name / Description :") == 0
X		|| strcmp (line, ";Field name :") == 0
X		|| strcmp (line, ";SQL>") == 0)
X	{	pushline (line);
X		return (1);
X	}
X	pushline (line);
X	return (0);
X}
X
X
X/****************************************************************************
X*	get_lines (line)														*
X*	Read and return the next line if it not  a Block or Field special line.	*
X*	If it is, push it back for another read.								*
X*	Used for scanning for sql text in a FIELD trigger.						*
X****************************************************************************/
X
Xget_lines (line)
Xchar	*line;
X{
X	if (getline (line) == NULL)
X		return (1);
X	if (strcmp (line, ";Block name / Description :") == 0
X		|| strcmp (line, ";Field name :") == 0)
X	{	pushline (line);
X		return (1);
X	}
X	return (0);
X}
X
X
X/****************************************************************************
X*	gathersql (blockname, fieldname, line)									*
X*	Get the sql text for FIELD triggers.									*
X****************************************************************************/
X
Xgathersql (blockname, fieldname, line)
Xchar	*blockname, *fieldname, *line;
X{	int	v;
X
X	while (get_lines (line) == 0)
X	{	if (strcmp (line, ";SQL>") == 0)
X		{
X			if (getline (line) == NULL)				/* blank or line with '/' */
X				return;
X			if (*line == '\0')						/* blank line means no query */
X				continue;
X			printf ("--> %s\n", line);				/* contains trigger type	*/
X			if (getline (line) == NULL)				/* then a line with '/' only */
X				return;
X			getline (line);							/* and a line   with SQL	*/
X			if (strcmp (line, ";SQL>") == 0)
X			{	for ( ;; )
X				{
X					v = display_sql (line);
X					if (v <= 0)
X						break;
X					skip (line, 4);
X				}
X			}
X		}
X	}
X}
X
X/****************************************************************************
X*	display_sql (line)														*
X*	Display all lines up to the first line that is fully blank or has		*
X*	a / as the first character.  This is used to display an SQL trigger.	*
X****************************************************************************/
X
Xdisplay_sql (line)
Xchar	*line;
X{
X	while (getline (line) != NULL  &&  *line != '%')
X	{
X		if (*line == '/'  ||  *line == '\0')
X			break;
X		if (*line == ';')
X		{	if (strcmp (line, ";SQL>") == 0)
X			{	pushline (line);
X				return (-1);
X			}
X			else
X				printf ("%s\n", line);
X		}
X		else
X			printf ("    %s\n", line);
X	}
X	return ((int) *line);
X}
END_OF_FILE
if test 9367 -ne `wc -c <'pform.c'`; then
    echo shar: \"'pform.c'\" unpacked with wrong size!
fi
# end of 'pform.c'
fi
if test -f 'index.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'index.c'\"
else
echo shar: Extracting \"'index.c'\" \(3627 characters\)
sed "s/^X//" >'index.c' <<'END_OF_FILE'
X/* ta=4 */
X/*	display the form comment for .inp files	and all tables used in blocks
X    or in list values.  optionally display all global variables used
X
X	usage:    index [-f] [-n] [-g] f1.inp f2.inp ...
X	
X		where:    -f = prefix all lines with the .inp file name
X		          -n = prefix all lines with sequential line numbers
X		          -g = show all global variables used
X
X	Note:  the line number and file names prefix are useful for
X	       the generation of "sorted cross-references".
X
XAuthor:   Tony Field      ..uunet!utai!calgary!ajfcal!tony
X*/
X
X#include <stdio.h>
X
XFILE	*fp;
Xchar	hdr[100], line[500];
X
Xmain (argc, argv)
Xint	argc;
Xchar	*argv[];
X{
X	int		i, j, last, printed, didprint;
X	int		start, prefix, globals, numbers, fnames, cnum;
X	char	name[100], block[100];
X	
X	prefix = globals = numbers = fnames = 0;
X
X	for (start = 1;  start < argc;  start++)
X	{
X		if (*argv[start] == '-')
X		{
X			switch (toupper (argv[start][1]))
X			{
X			case 'F':
X				fnames = 1;
X				break;
X			case 'G':
X				globals = 1;
X				break;
X			case 'N':
X				numbers = 1;
X			default:
X				break;
X			}
X		}
X		else break;
X	}
X	prefix = fnames | numbers;
X	
X	*name = '\0';
X	for (i = start;  i < argc;  i++)
X	{
X		fp = fopen (argv[i], "r");
X
X		lead (numbers, i, 0, fnames, argv[i]);
X		printf ("\n");
X		lead (numbers, i, 1, fnames, argv[i]);
X		printf ("%-15s\n", argv[i]);
X		didprint = 0;
X		{	*name = *block = '\0';
X			cnum = 10;
X			while (fgets (line, 490, fp) != NULL)
X			{	if (*line == ';'  &&  line[40] == '-')
X				{	while (fgets (line, 490, fp) != NULL)
X					{
X						if (strncmp (line, ";Application Title", 18) == 0)
X							break;
X						lead (numbers, i, cnum++, fnames, argv[i]);
X						printf ("    %s", line+1);
X						didprint=1;
X					}
X					if (didprint == 0)
X					{
X						lead (numbers, i, 10, fnames, argv[i]);
X						puts ("    NO COMMENT");
X					}
X					while (fgets (line, 490, fp) != NULL)
X					{	if (strncmp (line, ";Block name / Description", 20) == 0)
X						{
X							fgets (line, 490, fp);
X							if ((line[0] >= 'A'  &&  line[0] <= 'z')
X							    ||  (line[0] == '*'  && line[1] >= 'A'))
X							{
X								j = 0;
X								while (line[j])
X								{
X									if (line[j] == '/')
X									{
X										line[j] = '\0';
X										break;
X									}
X									j++;
X								}
X								lead (numbers, i, 903, fnames, argv[i]);
X								if (*line == '*')
X									printf ("    Table: %s\n", line + 1);
X								else
X									printf ("    Table: %s\n", line);
X							}
X						}					
X						else if (strncmp (line, ";Lowest value", 12) == 0)
X						{	fgets (line, 490, fp);
X							if (line[0] == '@')
X							{
X								lead (numbers, i, 904, fnames, argv[i]);
X								printf ("    Listv: %s", line + 1);
X							}
X						}
X						else if (globals  &&  tscan (line, "GLOBAL.") >= 0)
X						{
X							lead (numbers, i, 905, fnames, argv[i]);
X							printf ("    %s", line);
X						}
X					}
X				}
X			}
X			
X			fclose (fp);
X		}
X	}				
X}
X/************************************************
X*		t_scan (s,t)							*
X*		char	s[],t[];						*
X*												*
X*	Index function as defined in K&R			*
X*	Look for string t in s						*
X*												*
X*	return -1 if t does not exits in s			*
X*	else return array position of first			*
X*	character match								*
X************************************************/
X
X
Xtscan (s, t)
Xchar 	s[], t[];
X{
X	register int	i, j, k;
X	for (i = 0;  s[i] != '\0';  i++)
X	{	for (j = i, k=0;  t[k] != '\0'  &&  s[j] == t[k];  j++, k++)
X			;
X		if (t[k] == '\0')
X			return (i);
X	}
X	return (-1);
X}
X
Xlead (numbers, fno, lno, fnames, fn)
Xint	numbers, fno, lno, fnames;
Xchar	*fn;
X{
X	if (numbers)
X		printf ("%3d %3d ", fno, lno);
X	if (fnames)
X		printf ("%-15s ",fn);
X}
X
END_OF_FILE
if test 3627 -ne `wc -c <'index.c'`; then
    echo shar: \"'index.c'\" unpacked with wrong size!
fi
# end of 'index.c'
fi
echo shar: End of shell archive.
exit 0
-- 
+------------------------------------
|  Tony Field                             ..uunet!utai!calgary!ajfcal!tony
|  Co-Design Information Systems Ltd.
|  Calgary, Alberta, Canada                 voice: (403) 266-3239