316 lines
9.5 KiB
Plaintext
316 lines
9.5 KiB
Plaintext
ODBC support for scsh 0.6.x
|
|
===========================
|
|
|
|
This directory contains bindings to Unix ODBC libraries, which make it
|
|
possible to call any ODBC functions from scsh directly. At the moment
|
|
ODBC support is not part of the scsh distribution, since ODBC support
|
|
is in an early stage of development -- to put it another way, it's for
|
|
thrill seekers only! The code is complete, but needs testing. So,
|
|
please let us know if you find a bug. ODBC supports also lacks some
|
|
documentation.
|
|
|
|
1. Building scsh with ODBC support
|
|
|
|
I recommend to use the scsh version from CVS. However, it might work
|
|
with scsh-releases 0.6.1 or newer to. Be sure to have a ODBC
|
|
implementation for Unix, like unixODBC or iODBC -- both seem to work
|
|
fine. Apply the following patch:
|
|
|
|
Index: autogen.sh
|
|
===================================================================
|
|
RCS file: /cvsroot/scsh/scsh-0.6/autogen.sh,v
|
|
retrieving revision 1.7
|
|
diff -u -r1.7 autogen.sh
|
|
--- autogen.sh 12 Feb 2002 16:26:05 -0000 1.7
|
|
+++ autogen.sh 23 Apr 2003 15:23:43 -0000
|
|
@@ -2,7 +2,8 @@
|
|
|
|
autoheader &&
|
|
autoconf &&
|
|
-./configure &&
|
|
+./configure --with-iODBC=/afs/wsi/i386_fbsd46 &&
|
|
+##./configure --with-iODBC=/usr/lib &&
|
|
touch scsh/*.c &&
|
|
touch build/filenames.scm &&
|
|
rm -f scheme48.image cig/cig.image scsh/scsh.image &&
|
|
@@ -12,5 +13,4 @@
|
|
make i-know-what-i-am-doing &&
|
|
make c/scheme48.h&&
|
|
make linker &&
|
|
-make build/initial.image &&
|
|
-make distclean
|
|
+make build/initial.image
|
|
Index: configure.in
|
|
===================================================================
|
|
RCS file: /cvsroot/scsh/scsh-0.6/configure.in,v
|
|
retrieving revision 1.28
|
|
diff -u -r1.28 configure.in
|
|
--- configure.in 16 Apr 2003 12:41:36 -0000 1.28
|
|
+++ configure.in 23 Apr 2003 15:23:43 -0000
|
|
@@ -373,7 +373,30 @@
|
|
AC_SUBST(LIBS)
|
|
AC_SUBST(TMPDIR)
|
|
|
|
-
|
|
+AC_ARG_WITH(unixODBC,
|
|
+ [ --with-unixODBC=DIR Support for unixODBC ],
|
|
+ [ with_unixodbc=$withval ],
|
|
+ [ with_unixodbc=no ]
|
|
+ )
|
|
+if test "$with_unixodbc" != no; then
|
|
+ odbc_includes="-I$with_unixodbc/include"
|
|
+ odbc_libs="-lodbc -L$with_unixodbc/lib"
|
|
+ AC_SUBST(odbc_includes)
|
|
+ AC_SUBST(odbc_libs)
|
|
+fi
|
|
+
|
|
+AC_ARG_WITH(iODBC,
|
|
+ [ --with-iODBC=DIR Support for iODBC ],
|
|
+ [ with_iodbc=$withval ],
|
|
+ [ with_iodbc=no ]
|
|
+ )
|
|
+if test "$with_iodbc" != no; then
|
|
+ odbc_includes="-I$withval/include"
|
|
+ odbc_libs="-liodbc -L$withval/lib"
|
|
+ AC_SUBST(odbc_includes)
|
|
+ AC_SUBST(odbc_libs)
|
|
+fi
|
|
+
|
|
AC_CONFIG_FILES(Makefile scsh/endian.scm scsh-config)
|
|
AC_CONFIG_COMMANDS([scsh-config+x],[chmod +x scsh-config])
|
|
AC_OUTPUT
|
|
Index: Makefile.in
|
|
===================================================================
|
|
RCS file: /cvsroot/scsh/scsh-0.6/Makefile.in,v
|
|
retrieving revision 1.61
|
|
diff -u -r1.61 Makefile.in
|
|
--- Makefile.in 10 Mar 2003 12:13:02 -0000 1.61
|
|
+++ Makefile.in 23 Apr 2003 15:23:43 -0000
|
|
@@ -8,8 +8,8 @@
|
|
VPATH = @srcdir@
|
|
CC = @CC@
|
|
DEFS = @DEFS@
|
|
-LIBS = @LIBS@
|
|
-CFLAGS = @CFLAGS@
|
|
+LIBS = @LIBS@ @odbc_libs@
|
|
+CFLAGS = @CFLAGS@ @odbc_includes@
|
|
INSTALL = @INSTALL@
|
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
|
INSTALL_DATA = @INSTALL_DATA@
|
|
@@ -47,7 +47,8 @@
|
|
# BUILD_RUNNABLE has to be Scheme 48 0.53. This is used for builds directly
|
|
# out of the CVS repository.
|
|
# We cannot use Scsh here since -i is not understood.
|
|
-BUILD_RUNNABLE = /afs/wsi/i386_fbsd32/bin/scheme48
|
|
+#BUILD_RUNNABLE = /afs/wsi/ppc_macx55/scheme48-0.53/bin/scheme48
|
|
+BUILD_RUNNABLE = /afs/wsi/i386_fbsd32/scheme48-0.53/bin/scheme48
|
|
RUNNABLE = scsh
|
|
MANPAGE = $(RUNNABLE).$(manext)
|
|
LIB = $(libdir)/$(RUNNABLE)
|
|
@@ -133,7 +134,7 @@
|
|
scsh/userinfo1.o \
|
|
scsh/sighandlers1.o \
|
|
scsh/libscsh.o \
|
|
- scsh/md5.o
|
|
+ scsh/md5.o
|
|
|
|
SCSH_INITIALIZERS = s48_init_syslog s48_init_posix_regexp \
|
|
s48_init_userinfo s48_init_sighandlers \
|
|
@@ -169,16 +170,23 @@
|
|
# External code to include in the VM
|
|
# After changing any of these you should delete `scheme48vm' and remake it.
|
|
|
|
-EXTERNAL_OBJECTS = $(SOCKET_OBJECTS) $(LOOKUP_OBJECTS)
|
|
-EXTERNAL_FLAGS = $(SOCKET_FLAGS)
|
|
+EXTERNAL_OBJECTS = $(SOCKET_OBJECTS) $(LOOKUP_OBJECTS) $(ODBC_OBJECTS)
|
|
+EXTERNAL_FLAGS = $(SOCKET_FLAGS) $(ODBC_FLAGS)
|
|
+EXTERNAL_LDFLAGS = $(SOCKET_LD_FLAGS) $(ODBC_LD_FLAGS)
|
|
EXTERNAL_INITIALIZERS = $(ADDITIONAL_INITIALIZER) $(SOCKET_INITIALIZERS) \
|
|
$(LOOKUP_INITIALIZERS) \
|
|
$(SCSH_INITIALIZERS) $(SRFI_INITIALIZERS) \
|
|
+ $(ODBC_INITIALIZERS) \
|
|
s48_init_cig
|
|
|
|
|
|
# Rules for any external code.
|
|
|
|
+scsh/odbc/odbc.o: scsh/odbc/odbc.h
|
|
+
|
|
+ODBC_OBJECTS = scsh/odbc/odbc.o
|
|
+ODBC_INITIALIZERS = s48_init_odbc
|
|
+
|
|
# Socket rules
|
|
|
|
c/unix/socket.o: c/scheme48.h c/fd-io.h c/event.h
|
|
@@ -837,7 +845,10 @@
|
|
scsh/rx/re-high.scm \
|
|
scsh/rx/regexp.scm \
|
|
scsh/rx/re-low.scm \
|
|
- scsh/rx/regress.scm
|
|
+ scsh/rx/regress.scm \
|
|
+ scsh/odbc/odbc-interfaces.scm \
|
|
+ scsh/odbc/odbc-packages.scm \
|
|
+ scsh/odbc/odbc.scm
|
|
# scsh/dbm.scm db.scm ndbm.scm
|
|
# jcontrol
|
|
|
|
@@ -861,7 +872,9 @@
|
|
$(srcdir)/scsh/rx/packages.scm \
|
|
$(srcdir)/scsh/scsh-package.scm \
|
|
$(srcdir)/scsh/lib/ccp-pack.scm \
|
|
- $(srcdir)/scsh/lib/char-package.scm
|
|
+ $(srcdir)/scsh/lib/char-package.scm \
|
|
+ $(srcdir)/scsh/odbc/odbc-interfaces.scm \
|
|
+ $(srcdir)/scsh/odbc/odbc-packages.scm
|
|
|
|
opens = floatnums scsh ccp-lib scsh-top-package scsh-here-string-hax \
|
|
srfi-1 srfi-13 srfi-14 # srfi-14 is also exported by scsh
|
|
|
|
|
|
This will add some rules to Makefile and add two options to configure:
|
|
--with-iODBC=PATH and --with-unixODBC=PATH.
|
|
|
|
Now it's time to build scsh. Edit the call to configure in autgen.sh to
|
|
your needs, e.g.:
|
|
|
|
./configure --with-iODBC=/usr/local &&
|
|
|
|
Don't forget the && at the end of line! Now, run autogen.sh to build
|
|
the VM and all that stuff. Run make to build scsh. If the build
|
|
suceeds, tap yourself on the shoulder, that's important, it might the
|
|
last sense of achievement from now on.
|
|
|
|
2. Running scsh with ODBC support
|
|
|
|
Type ./scshvm -i scsh/scsh.image -- that's it!
|
|
|
|
3. How do I use ODBC support?
|
|
|
|
If you installed the odbc-module-patch, simply type ,open odbc. If you
|
|
have installed dynamic ODBC libraries make sure your system can find
|
|
them, e.g. put the path in your LD_LIBRARY_PATH. This should look like
|
|
this:
|
|
|
|
[knauel@jimi scsh-0.6.cvs] ./scshvm -i scsh/scsh.image
|
|
Welcome to scsh 0.6.3 (Health Reform)
|
|
Type ,? for help.
|
|
> ,open odbc
|
|
Load structure odbc (y/n)? y
|
|
[odbc ./scsh/odbc/odbc-bindcol.scm ./scsh/odbc/odbc.scm]
|
|
> ,exit
|
|
|
|
This is an example entry for ~/.odbc.ini:
|
|
|
|
[test]
|
|
DSN = mysql1
|
|
Driver = /afs/informatik.uni-tuebingen.de/pu/src/build/knauel/i386_fbsd43/lib/libmyodbc3.so
|
|
Server = localhost
|
|
Port = 3306
|
|
User = odbc
|
|
Password= geheim
|
|
TraceFile= stderr
|
|
Trace = on
|
|
|
|
It may be necessary to help your ODBC driver manager to find that file
|
|
be setting the environment variable ODBCINI.
|
|
|
|
Let's see what data sources are known to the system:
|
|
|
|
(let* ((env-handle (odbc-alloc-environment-handle))
|
|
(data-sources (odbc-sql-data-sources env-handle)))
|
|
(for-each
|
|
(lambda (pair)
|
|
(display "data source: ")
|
|
(display (car pair))
|
|
(newline)
|
|
(display "using driver: ")
|
|
(display (cdr pair))
|
|
(newline))
|
|
data-sources))
|
|
|
|
Don't worry about freeing handles -- this will happen automatically
|
|
when the scheme variable gets garbage collected.
|
|
|
|
This example shows how you can read the information from ODBC's
|
|
diag-recs in case an error occurs, which is to happen very likely:
|
|
|
|
(define (display-errors handle)
|
|
(let ((recs (odbc-sql-get-diag-recs handle)))
|
|
(if (not (null? recs))
|
|
(for-each (lambda (rec)
|
|
(newline)
|
|
(display "state: ")
|
|
(display (odbc-diag-sql-state rec))
|
|
(newline)
|
|
(display "native error: ")
|
|
(display (odbc-diag-native-error rec))
|
|
(newline)
|
|
(display "message: ")
|
|
(display (odbc-diag-message rec))
|
|
(newline))
|
|
recs)
|
|
(begin
|
|
(display "No error messages (so far ;-)")
|
|
(newline)))))
|
|
|
|
Not let's read some stuff from the database! Say we have a database
|
|
with four columns a through d, where a,b,c are integer columns and d
|
|
is text. Using the fancy odbc-sql-bindcol functions that's pretty
|
|
easy:
|
|
|
|
,open low-odbc
|
|
,open low-odbc-constants
|
|
|
|
(define (get-env-handle)
|
|
(call-with-values
|
|
odbc-alloc-environment-handle
|
|
(lambda (status-code env-handle)
|
|
(if (odbc-call-successful? status-code)
|
|
env-handle
|
|
(error "error allocating environment handle")))))
|
|
|
|
(define (get-conn-handle env-handle)
|
|
(call-with-values
|
|
(lambda ()
|
|
(odbc-alloc-connection-handle env-handle))
|
|
(lambda (status-code conn-handle)
|
|
(if (odbc-call-successful? status-code)
|
|
conn-handle
|
|
(error "error allocating connection handle")))))
|
|
|
|
(define (get-stmt-handle conn-handle)
|
|
(call-with-values
|
|
(lambda ()
|
|
(odbc-alloc-statement-handle conn-handle))
|
|
(lambda (status-code stmt-handle)
|
|
(if (odbc-call-successful? status-code)
|
|
stmt-handle
|
|
(error "error allocating statement handle")))))
|
|
|
|
(define env-handle (get-env-handle))
|
|
(define conn-handle (get-conn-handle env-handle))
|
|
|
|
(odbc-sql-connect conn-handle "pgfbsd" "test" "geheim")
|
|
|
|
(define stmt-handle (get-stmt-handle conn-handle))
|
|
|
|
(odbc-sql-execute-direct stmt-handle "select * from abcd")
|
|
|
|
(define col-a (odbc-sql-bindcol stmt-handle 1 sql-c-long 1))
|
|
(define col-b (odbc-sql-bindcol stmt-handle 2 sql-c-long 1))
|
|
(define col-c (odbc-sql-bindcol stmt-handle 3 sql-c-long 1))
|
|
(define col-d (odbc-sql-bindcol stmt-handle 4 sql-c-char 400))
|
|
|
|
(let lp ((retcode (odbc-sql-fetch stmt-handle))
|
|
(result '()))
|
|
(if (or (odbc-call-successful? retcode) (equal? retcode sql-no-data))
|
|
(if (equal? retcode sql-no-data)
|
|
result
|
|
(lp (odbc-sql-fetch stmt-handle)
|
|
(cons (list (col-a) (col-b) (col-c) (col-d)) result)))
|
|
(error "Could not SQLFetch()")))
|
|
|
|
Please let me know, if you find some bugs. I hereby promise to
|
|
complete the documentation as soon as possible!
|
|
|
|
Eric Knauel <knauel@informatik.uni-tuebingen.de> |