[comp.sys.atari.st] SQL Database Access from C

ron@argus.UUCP (Ron DeBlock) (10/16/89)

A few days ago, I promised to post an article demostrating how to 
use Regent Software's SQL Add-On with C.  Sorry for the delay - 
my ST was at my dealer getting TOS 1.4 installed (yay!).

I needed a cheap database for a school project, and I found SQL Add-On
in E. Arthur Brown's catalog for $24.95.  I preferred something I could
use with Mark Williams C, but decided that GFA Basic would be OK.

The SQL Add-On works well, but the documentation is not great and the
SQL is not standard.  Syntax is slightly different and it has a funky
way of dealing with queries returning multiple rows.  However, the
price is right.

Regent claims that files are compatible with RegentBase.  It is
supposed to work with GFA Basic V2 and V3.

The Add-On is a terminate-and-stay-resident program (TSR).  It loads
the SQL processor and adds a new xbios call (xbios(500)).  It takes up
over 300 K of ram (buffers, I guess).

To use the Add-On, run the TSR program first.  Use GFA Basic's xbios()
call to call xbios(500).  This returns the address of the SQL processing
function.   The GFA Call function is then used to execute SQL statements.

I reasoned that there is nothing preventing me from doing the same thing
in Mark Williams C.  In C, if you know the address of a function, you
can call it.

By reading the GFA Basic and MWC manuals, and spending some time with the
MWC debugger, I worked it out.  The SQL function expects two arguments
on the stack:
	number of arguments (int, on top of stack)
	arguement buffer (pointer to array of pointers to char buffers)

Below is a sample C program with comments.  Feel free to email if you have
questions (email may no work - post here or use snail mail in that case).


Regent Software
PO Box 14628
Long Beach, CA 90803-1208
(213) 439-9664

E. Arthur Brown
3404 Pawnee Drive
Alexandria, MN 56308
(612) 762-8847

-----------------------------------------

/*
   Demonstration of using Regent SQL Add-On for GFA Basic with Mark Williams
   C.

   Copyright 1989 by Ronald J. DeBlock, Jr.
   May be used or distributed freely as long as this copyright notice
   is included.
*/

#include <stdio.h>

main()
{
	/* pointer to function */
	typedef void (*PFI)();

	extern long xbios();
	
	/* sql is a pointer to a function returning void */
	PFI sql;

	/* these char arrays hold arguments for the sql call */
	/* fields */
	char field1[21], field2[3], field3[21];
	/* error code */
	char error[10];
	/* command string */
	char command[100];

	/* this array will hold pointers to the command, error and field
	arguments.  Make the array larger if more fields are used. */
	char *args[5];

	/* the first field in the array points to SQL command string */
	args[0] = command;
	/* second points to a buffer used to return error codes */
	args[1] = error;
	/* all other fields point to buffers where the column results
	   of a query will be placed - one buffer per culumn returned */
	args[2] = field1;
	args[3] = field2;
	args[4] = field3;

	/* A program is run before the SQL Add-On can be used.  It
	   loads the SQL processor and creates a new xbios call.
	   The new xbios call returns the address of the SQL processing
	   routine. */
	sql = (PFI)xbios(500);
	printf("sql = %U\n",(long)sql);
	

	/* This program assumes that a table has been created using the
	   SQL statement
 		CREATE TABLE phonelist name CHAR(20), age INT(2),
			phone CHAR(20);
	  and some records have been added.  The demo program included with
	  the product (written in GFA Basic) will do this.  */

	/* set up the command string - SELECT [1] is Regent's funky
	   way of setting up a cursor */
	strcpy(command,"SELECT [1] * FROM phonelist;");

	/* Call the SQL processor.  The function expects to see the 
	number of arguments on the top of the stack, followed by a
	pointer to the argument array.
		*** WARNING ***
	This is compiler dependent!! Mark Williams C pushes arguments 
	right to left.  Your compiler may differ.  If so, reverse the
	order of the arguments and it should work. */

	(*sql)(5,args);
	printf("error: %s\n",error);
	printf("%s   %s   %s\n",field1, field2, field3);

	/* execute another commend to retrieve the next row.  
	   SELECT NEXT is Regent's funky way of dealing with cursors */
	strcpy(command,"SELECT NEXT * FROM phonelist;");
	(*sql)(5,args);
	printf("error: %s\n",error);
	printf("%s   %s   %s\n",field1, field2, field3);
}


-------------------------------------
-- 
Ron DeBlock	N2JSO
Net: ...!rutgers!galaxy!argus
US Mail: 42 Davis Street, Phillibsburg, NJ 08865 USA