Subject: Connect support in 4GL??
Newsgroups: comp.databases.informix

From: [email-masked] (Jon C. Vemo)
Date: 7 Jul 1995 13:23:07 -0400

I have a logging database and a non-logging database. I want to be able to 
access data on one, from the other, with 4GL. Because of the differences in 
logging, I seem to be forced into using the "connect" feature of OnLine 7.1.

However according to TFM, the "connect" statement appears to only be 
supported with the embedded language products, and dbaccess. Can anyone 
confirm or deny, that the current version of 4GL (6.01) does not support 
"connect"?? Will there be a version of 4GL that supports "connect"?? and when??

From: [email-masked] (Jonathan Leffler)
Date: 7 Jul 1995 15:43:05 -0400

There is no direct support for CONNECT, DISCONNECT or SET CONNECTION in
version 6.0x I4GL, nor are there any plans for it to be supported.
However, one of the components of the I4GL compilation system is the 6.0x
ESQL/C compiler, and it does understand CONNECT et al, and therefore you
can write I4GL-callable ESQL/C functions to handle the connections for you.
You can compile these with the c4gl script and build them into a general
purpose library and link them into programs as required.

Note that the CONNECT, DISCONNECT and SET CONNECTION statements are not
preparable, so the normal ruse of doing PREPARE and EXECUTE will not work.

Also note that CONNECT et al were introduced in Version 6.00 and are
therefore available in all later versions too.

From: [email-masked] (Jonathan Leffler)
Date: 7 Jul 1995 18:18:04 -0400

Here is a set of I4GL callable ESQL/C code for handling CONNECT, etc.  It
has been tested and seems to work -- but the connect_dbase_by_name_user()
or connect_dbase_by_name_user_wct() routines both failed consistently with
error -952, which I think simply means that some portion of my machine
setup is wrong, rather than the code is not working.  There is the sample
piece of I4GL code included, though I've changed the login name and
password embedded in the code.  I haven't provided code for building this
into a custom p-code runner.  Note that the SET CONNECTION 'db-environment'
operation is not supported by this code because I couldn't get it to work.

Read the README file for version information, etc.

This has been needed for a while, which is why I did it...

Yours,
Jonathan Leffler ([email-masked]) #include <disclaimer.h>

:	"@(#)shar.sh	1.9"
#! /bin/sh
#
#	This is a shell archive.
#	Remove everything above this line and run sh on the resulting file.
#	If this archive is complete, you will see this message at the end:
#	"All files extracted"
#
#	Created: Fri Jul  7 14:17:56 PDT 1995 by johnl at Informix Software Ltd.
#	Files archived in this archive:
#	README
#	connect.ec
#	connect.h
#	kk.4gl
#	popstr.c
#
#--------------------
if [ -f README -a "$1" != "-c" ]
then echo shar: README already exists
else
echo 'x - README (2529 characters)'
sed -e 's/^X//' >README <<'SHAR-EOF'
XCode to handle CONNECT, DISCONNECT and SET CONNECTION statements in I4GL
X========================================================================
X
XThe code accompanying this is designed for use with ANSI C compilers --
Xit uses prototypes -- and will work with version 6.00, 6.01 or 6.02 I4GL.
XThere is no reason to suppose it will not work with other, later versions
Xof I4GL.
X
XIf you are compiling with 6.00, you will need the popstring() routine
Xfrom popstr.c; if you are using 6.01 or later, the routine is in the I4GL
Xlibrary and popstr.o should not be linked -- it will cause the link to
Xfail.  If you are using 6.02 or later, you can use the header 'fglsys.h'
Xto pick up the prototypes for the routines popstring(), retint() and
Xfgl_fatal().
X
XThe I4GL programmer must invent one or more distinct connection names,
Xand these will be used to specify the connection names.  Establishing the
Xuser ID and the authorisation string (password) are also problems for the
Xprogrammer.
X
XThe routines available are:
X
X    DEFINE
X        dbase   CHAR(80),
X        uconn   CHAR(18),
X        uname   CHAR(18),
X        uauth   CHAR(18)
X    DEFINE
X        retval  INTEGER
X
X    LET dbase = "..."
X    LET uconn = "..."
X    LET uname = "..."
X    LET uauth = "..."
X
X    LET retval = connect_default()
X    LET retval = connect_dbase_by_name(dbase, uconn)
X    LET retval = connect_dbase_by_name_user(dbase, uconn, uname, uauth)
X
X    LET retval = connect_default_wct()
X    LET retval = connect_dbase_by_name_wct(dbase, uconn)
X    LET retval = connect_dbase_by_name_user_wct(dbase, uconn, uname, uauth)
X
X    LET retval = disconnect_current()
X    LET retval = disconnect_default()
X    LET retval = disconnect_by_name(uconn)
X
X    LET retval = set_connect_default()
X    LET retval = set_connect_by_name(uconn)
X    LET retval = set_connect_db_env(dbase)
X
XIn all cases, the returned value is the same as SQLCA.SQLCODE.  Looking
Xat a 6.0x or later 'Informix Guide to SQL: Syntax' reference manual will
Xquickly reveal what this code does.  There is precious little difference
Xbetween the set_connect_by_name() and set_connect_db_env() routines,
Xexcept that the latter has more space for the variable string.  Note that
Xif you exceed the variable sizes specified above, the names will be
Xtruncated without warning, probably but not necessarily leading to
Xfailure.
X
XJonathan Leffler
XInformix Software Inc
X7th July 1995
X
XNB: This software is not supported by Informix Software Inc and is supplied
X"as is".  You use it at your own risk.
X
X@(#)README	1.1 95/07/07
SHAR-EOF
chmod 444 README
if [ `wc -c <README` -ne 2529 ]
then echo shar: README unpacked with wrong size
fi
# end of overwriting check
fi
#--------------------
if [ -f connect.ec -a "$1" != "-c" ]
then echo shar: connect.ec already exists
else
echo 'x - connect.ec (4213 characters)'
sed -e 's/^X//' >connect.ec <<'SHAR-EOF'
X/*
X@(#)File:            connect.ec
X@(#)Version:         1.3
X@(#)Last changed:    95/07/07
X@(#)Purpose:         I4GL interface to CONNECT, DISCONNECT, SET CONNECTION
X@(#)Author:          J Leffler
X@(#)Copyright:       (C) JLSS 1995
X@(#)Product:         :PRODUCT:
X*/
X
X/*TABSTOP=4*/
X
X/* -- Include Files */
X
X#include <sqlca.h>
X#include "connect.h"
X
X#ifndef lint
Xstatic char     sccs[] = "@(#)connect.ec	1.3 95/07/07";
X#endif
X
Xstatic char module_name[] = "connect.ec";
X
X/* CONNECT TO DEFAULT */
Xint connect_default(int n)
X{
X	if (n != 0)
X		fgl_fatal(module_name, __LINE__, -1318);
X	EXEC SQL CONNECT TO DEFAULT;
X	retint(sqlca.sqlcode);
X	return(1);
X}
X
X/* CONNECT TO "db" AS "conn_name" */
Xint connect_dbase_by_name(int n)
X{
X	EXEC SQL BEGIN DECLARE SECTION;
X	char	dbase[MAX_DBASE_NAME + 1];
X	char	uconn[MAX_CONN_NAME + 1];
X	EXEC SQL END DECLARE SECTION;
X
X	if (n != 2)
X		fgl_fatal(module_name, __LINE__, -1318);
X	popstring(uconn, sizeof(uconn));
X	popstring(dbase, sizeof(dbase));
X	EXEC SQL CONNECT TO :dbase AS :uconn;
X	retint(sqlca.sqlcode);
X	return(1);
X}
X
X/* CONNECT TO "db" AS "conn_name" USER 'uname' USING 'auth' */
Xint connect_dbase_by_name_user(int n)
X{
X	EXEC SQL BEGIN DECLARE SECTION;
X	char	dbase[MAX_DBASE_NAME + 1];
X	char	uconn[MAX_CONN_NAME + 1];
X	char	uname[MAX_USER_NAME + 1];
X	char	uauth[MAX_AUTH_NAME + 1];
X	EXEC SQL END DECLARE SECTION;
X
X	if (n != 4)
X		fgl_fatal(module_name, __LINE__, -1318);
X	popstring(uauth, sizeof(uauth));
X	popstring(uname, sizeof(uname));
X	popstring(uconn, sizeof(uconn));
X	popstring(dbase, sizeof(dbase));
X	EXEC SQL CONNECT TO :dbase AS :uconn USER :uname USING :uauth;
X	retint(sqlca.sqlcode);
X	return(1);
X}
X
X
X/* CONNECT TO DEFAULT WITH CONCURRENT TRANSACTION */
Xint connect_default_wct(int n)
X{
X	if (n != 0)
X		fgl_fatal(module_name, __LINE__, -1318);
X	EXEC SQL CONNECT TO DEFAULT
X				WITH CONCURRENT TRANSACTION;
X	retint(sqlca.sqlcode);
X	return(1);
X}
X
X/* CONNECT TO "db" AS "conn_name" WITH CONCURRENT TRANSACTION */
Xint connect_dbase_by_name_wct(int n)
X{
X	EXEC SQL BEGIN DECLARE SECTION;
X	char	dbase[MAX_DBASE_NAME + 1];
X	char	uconn[MAX_CONN_NAME + 1];
X	EXEC SQL END DECLARE SECTION;
X
X	if (n != 2)
X		fgl_fatal(module_name, __LINE__, -1318);
X	popstring(uconn, sizeof(uconn));
X	popstring(dbase, sizeof(dbase));
X	EXEC SQL CONNECT TO :dbase AS :uconn
X				WITH CONCURRENT TRANSACTION;
X	retint(sqlca.sqlcode);
X	return(1);
X}
X
X/* CONNECT TO "db" AS "conn_name" USER 'uname' USING 'auth'
X		WITH CONCURRENT TRANSACTION */
Xint connect_dbase_by_name_user_wct(int n)
X{
X	EXEC SQL BEGIN DECLARE SECTION;
X	char	dbase[MAX_DBASE_NAME + 1];
X	char	uconn[MAX_CONN_NAME + 1];
X	char	uname[MAX_USER_NAME + 1];
X	char	uauth[MAX_AUTH_NAME + 1];
X	EXEC SQL END DECLARE SECTION;
X
X	if (n != 4)
X		fgl_fatal(module_name, __LINE__, -1318);
X	popstring(uauth, sizeof(uauth));
X	popstring(uname, sizeof(uname));
X	popstring(uconn, sizeof(uconn));
X	popstring(dbase, sizeof(dbase));
X	EXEC SQL CONNECT TO :dbase AS :uconn USER :uname USING :uauth
X				WITH CONCURRENT TRANSACTION;
X	retint(sqlca.sqlcode);
X	return(1);
X}
X
X
X/* DISCONNECT CURRENT */
Xint disconnect_current(int n)
X{
X	if (n != 0)
X		fgl_fatal(module_name, __LINE__, -1318);
X	EXEC SQL DISCONNECT CURRENT;
X	retint(sqlca.sqlcode);
X	return(1);
X}
X
X/* DISCONNECT DEFAULT */
Xint disconnect_default(int n)
X{
X	if (n != 0)
X		fgl_fatal(module_name, __LINE__, -1318);
X	EXEC SQL DISCONNECT DEFAULT;
X	retint(sqlca.sqlcode);
X	return(1);
X}
X
X/* DISCONNECT "conn_name" */
Xint disconnect_by_name(int n)
X{
X	EXEC SQL BEGIN DECLARE SECTION;
X	char	uconn[MAX_CONN_NAME + 1];
X	EXEC SQL END DECLARE SECTION;
X
X	if (n != 1)
X		fgl_fatal(module_name, __LINE__, -1318);
X	popstring(uconn, sizeof(uconn));
X	EXEC SQL DISCONNECT :uconn;
X	retint(sqlca.sqlcode);
X	return(1);
X}
X
X/* SET CONNECTION DEFAULT */
Xint set_connection_default(int n)
X{
X	if (n != 0)
X		fgl_fatal(module_name, __LINE__, -1318);
X	EXEC SQL SET CONNECTION DEFAULT;
X	retint(sqlca.sqlcode);
X	return(1);
X}
X
X/* SET CONNECTION "conn_name" */
Xint set_connection_by_name(int n)
X{
X	EXEC SQL BEGIN DECLARE SECTION;
X	char	uconn[MAX_CONN_NAME + 1];
X	EXEC SQL END DECLARE SECTION;
X
X	if (n != 1)
X		fgl_fatal(module_name, __LINE__, -1318);
X	popstring(uconn, sizeof(uconn));
X	EXEC SQL SET CONNECTION :uconn;
X	retint(sqlca.sqlcode);
X	return(1);
X}
SHAR-EOF
chmod 444 connect.ec
if [ `wc -c <connect.ec` -ne 4213 ]
then echo shar: connect.ec unpacked with wrong size
fi
# end of overwriting check
fi
#--------------------
if [ -f connect.h -a "$1" != "-c" ]
then echo shar: connect.h already exists
else
echo 'x - connect.h (1566 characters)'
sed -e 's/^X//' >connect.h <<'SHAR-EOF'
X/*
X@(#)File:            connect.h
X@(#)Version:         1.2
X@(#)Last changed:    95/07/07
X@(#)Purpose:         I4GL Header for CONNECT, DISCONNECT and SET CONNECTION
X@(#)Author:          J Leffler
X@(#)Copyright:       (C) JLSS 1995
X@(#)Product:         :PRODUCT:
X*/
X
X/*TABSTOP=4*/
X
X#ifndef CONNECT_H
X#define CONNECT_H
X
X#ifdef MAIN_PROGRAM
X#ifndef lint
Xstatic char connect_h[] = "@(#)connect.h	1.2 95/07/07";
X#endif	/* lint */
X#endif	/* MAIN_PROGRAM */
X
X/* -- Constant Definitions */
X
X#define MAX_CONN_NAME	18
X#define MAX_USER_NAME	18
X#define MAX_AUTH_NAME	18
X#define MAX_DBASE_NAME	80
X
X/* -- Declarations */
X
X/* CONNECT TO DEFAULT */
Xextern int connect_default(int n);
X/* CONNECT TO "db" AS "conn_name" */
Xextern int connect_dbase_by_name(int n);
X/* CONNECT TO "db" AS "conn_name" USER 'uname' USING 'auth' */
Xextern int connect_dbase_by_name_user(int n);
X
X/* CONNECT TO DEFAULT WITH CONCURRENT TRANSACTION */
Xextern int connect_default_wct(int n);
X/* CONNECT TO "db" AS "conn_name" WITH CONCURRENT TRANSACTION */
Xextern int connect_dbase_by_name_wct(int n);
X/* CONNECT TO "db" AS "conn_name" USER 'uname' USING 'auth'
X		WITH CONCURRENT TRANSACTION */
Xextern int connect_dbase_by_name_user_wct(int n);
X
X/* DISCONNECT CURRENT */
Xextern int disconnect_current(int n);
X/* DISCONNECT DEFAULT */
Xextern int disconnect_default(int n);
X/* DISCONNECT "conn_name" */
Xextern int disconnect_by_name(int n);
X
X/* SET CONNECTION DEFAULT */
Xextern int set_connection_default(int n);
X/* SET CONNECTION "conn_name" */
Xextern int set_connection_by_name(int n);
X
X#endif	/* CONNECT_H */
SHAR-EOF
chmod 444 connect.h
if [ `wc -c <connect.h` -ne 1566 ]
then echo shar: connect.h unpacked with wrong size
fi
# end of overwriting check
fi
#--------------------
if [ -f kk.4gl -a "$1" != "-c" ]
then echo shar: kk.4gl already exists
else
echo 'x - kk.4gl (1913 characters)'
sed -e 's/^X//' >kk.4gl <<'SHAR-EOF'
X
XMAIN
X
X    DEFINE
X        dbase   CHAR(80),
X        ucon1   CHAR(18),
X        ucon2   CHAR(18),
X        uname   CHAR(18),
X        uauth   CHAR(18)
X    DEFINE
X        retval  INTEGER
X
X    LET dbase = "stores"
X    LET ucon1 = "conn_1"
X    LET ucon2 = "conn_2"
X    LET uname = "ghenghis"
X    LET uauth = "The Kahn"
X
X	DISPLAY " No current connections "
X
X	DATABASE dbase
X	DISPLAY sqlca.sqlcode, " DATABASE"
X
X    LET retval = connect_dbase_by_name_wct(dbase, ucon1)
X	DISPLAY retval, " CONNECT BY NAME WCT"
X    LET retval = connect_dbase_by_name_user_wct(dbase, ucon2, uname, uauth)
X	DISPLAY retval, " CONNECT BY NAME AND USER WCT"
X
X    LET retval = set_connection_default()
X	DISPLAY retval, " SET CONNECT DEFAULT"
X    LET retval = set_connection_by_name(ucon1)
X	DISPLAY retval, " SET CONNECT BY NAME"
X
X    LET retval = set_connection_default()
X	DISPLAY retval, " SET CONNECT DEFAULT"
X    LET retval = disconnect_current()
X	DISPLAY retval, " DISCONNECT CURRENT"
X
X    LET retval = disconnect_by_name(ucon1)
X	DISPLAY retval, " DISCONNECT BY NAME"
X    LET retval = disconnect_by_name(ucon2)
X	DISPLAY retval, " DISCONNECT BY NAME"
X
X	DISPLAY " No current connections "
X
X    LET retval = connect_default_wct()
X	DISPLAY retval, " CONNECT DEFAULT WCT"
X    LET retval = disconnect_default()
X	DISPLAY retval, " DISCONNECT DEFAULT"
X
X	DISPLAY " No current connections "
X
X    LET retval = connect_default()
X	DISPLAY retval, " CONNECT DEFAULT"
X    LET retval = connect_dbase_by_name(dbase, ucon1)
X	DISPLAY retval, " CONNECT BY NAME"
X    LET retval = connect_dbase_by_name_user(dbase, ucon2, uname, uauth)
X	DISPLAY retval, " CONNECT BY NAME AND USER"
X
X    LET retval = disconnect_current()
X	DISPLAY retval, " DISCONNECT CURRENT"
X    LET retval = disconnect_default()
X	DISPLAY retval, " DISCONNECT DEFAULT"
X    LET retval = disconnect_by_name(ucon1)
X	DISPLAY retval, " DISCONNECT BY NAME"
X
X	DISPLAY " No current connections "
X
XEND MAIN
SHAR-EOF
chmod 664 kk.4gl
if [ `wc -c <kk.4gl` -ne 1913 ]
then echo shar: kk.4gl unpacked with wrong size
fi
# end of overwriting check
fi
#--------------------
if [ -f popstr.c -a "$1" != "-c" ]
then echo shar: popstr.c already exists
else
echo 'x - popstr.c (575 characters)'
sed -e 's/^X//' >popstr.c <<'SHAR-EOF'
X/*
X@(#)File:            popstr.c
X@(#)Version:         1.2
X@(#)Last changed:    90/04/05
X@(#)Purpose:         Pop string and strip trailing blanks
X@(#)Author:          J Leffler
X*/
X
X/* -- Declarations		*/
X
X#ifndef lint
Xstatic	char	sccs[] = "@(#)popstr.c	1.2 90/04/05";
X#endif
X
X/* -- Routine: popstring		*/
X
Xvoid	popstring(s, l)
Xchar	*s;		/* InOut: String to be stripped */
Xint		 l;		/* In:    Length of string      */
X{
X	register char *p = s + l - 1;
X
X	popquote(s,l);
X
X	if (l <= 1)
X		return;	/* Length 1 => "" */
X
X	while (p > s)
X		if (*--p != ' ')
X			break;
X	*(p+1) = '\0';
X}
SHAR-EOF
chmod 444 popstr.c
if [ `wc -c <popstr.c` -ne 575 ]
then echo shar: popstr.c unpacked with wrong size
fi
# end of overwriting check
fi
echo All files extracted
exit 0