Newsgroups: comp.databases.informix Subject: Connect support in 4GL?? From: jvemo@cyberspace.com (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: johnl@informix.com (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: johnl@informix.com (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 (johnl@informix.com) #include : "@(#)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 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 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.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 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 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